diff --git a/patch/kernel/sun8i-default/patch-3.4.39-40.patch b/patch/kernel/sun8i-default/0001-patch-3.4.39-40.patch similarity index 100% rename from patch/kernel/sun8i-default/patch-3.4.39-40.patch rename to patch/kernel/sun8i-default/0001-patch-3.4.39-40.patch diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.40-41.patch b/patch/kernel/sun8i-default/0001-patch-3.4.40-41.patch new file mode 100644 index 000000000..6233de7bb --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.40-41.patch @@ -0,0 +1,527 @@ +diff --git a/Makefile b/Makefile +index 3efde3d..90c3a6f 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 40 ++SUBLEVEL = 41 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h +index aa0f913..25e9734 100644 +--- a/arch/x86/include/asm/paravirt.h ++++ b/arch/x86/include/asm/paravirt.h +@@ -741,7 +741,10 @@ static inline void arch_leave_lazy_mmu_mode(void) + PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave); + } + +-void arch_flush_lazy_mmu_mode(void); ++static inline void arch_flush_lazy_mmu_mode(void) ++{ ++ PVOP_VCALL0(pv_mmu_ops.lazy_mode.flush); ++} + + static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, + phys_addr_t phys, pgprot_t flags) +diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h +index 8e8b9a4..faf2c04 100644 +--- a/arch/x86/include/asm/paravirt_types.h ++++ b/arch/x86/include/asm/paravirt_types.h +@@ -91,6 +91,7 @@ struct pv_lazy_ops { + /* Set deferred update mode, used for batching operations. */ + void (*enter)(void); + void (*leave)(void); ++ void (*flush)(void); + }; + + struct pv_time_ops { +@@ -680,6 +681,7 @@ void paravirt_end_context_switch(struct task_struct *next); + + void paravirt_enter_lazy_mmu(void); + void paravirt_leave_lazy_mmu(void); ++void paravirt_flush_lazy_mmu(void); + + void _paravirt_nop(void); + u32 _paravirt_ident_32(u32); +diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c +index ab13760..128323e 100644 +--- a/arch/x86/kernel/paravirt.c ++++ b/arch/x86/kernel/paravirt.c +@@ -263,6 +263,18 @@ void paravirt_leave_lazy_mmu(void) + leave_lazy(PARAVIRT_LAZY_MMU); + } + ++void paravirt_flush_lazy_mmu(void) ++{ ++ preempt_disable(); ++ ++ if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) { ++ arch_leave_lazy_mmu_mode(); ++ arch_enter_lazy_mmu_mode(); ++ } ++ ++ preempt_enable(); ++} ++ + void paravirt_start_context_switch(struct task_struct *prev) + { + BUG_ON(preemptible()); +@@ -292,18 +304,6 @@ enum paravirt_lazy_mode paravirt_get_lazy_mode(void) + return percpu_read(paravirt_lazy_mode); + } + +-void arch_flush_lazy_mmu_mode(void) +-{ +- preempt_disable(); +- +- if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) { +- arch_leave_lazy_mmu_mode(); +- arch_enter_lazy_mmu_mode(); +- } +- +- preempt_enable(); +-} +- + struct pv_info pv_info = { + .name = "bare hardware", + .paravirt_enabled = 0, +@@ -477,6 +477,7 @@ struct pv_mmu_ops pv_mmu_ops = { + .lazy_mode = { + .enter = paravirt_nop, + .leave = paravirt_nop, ++ .flush = paravirt_nop, + }, + + .set_fixmap = native_set_fixmap, +diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c +index 642d880..53272bd 100644 +--- a/arch/x86/lguest/boot.c ++++ b/arch/x86/lguest/boot.c +@@ -1333,6 +1333,7 @@ __init void lguest_init(void) + pv_mmu_ops.read_cr3 = lguest_read_cr3; + pv_mmu_ops.lazy_mode.enter = paravirt_enter_lazy_mmu; + pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mmu_mode; ++ pv_mmu_ops.lazy_mode.flush = paravirt_flush_lazy_mmu; + pv_mmu_ops.pte_update = lguest_pte_update; + pv_mmu_ops.pte_update_defer = lguest_pte_update; + +diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c +index e922e01..4a0a2e8 100644 +--- a/arch/x86/mm/fault.c ++++ b/arch/x86/mm/fault.c +@@ -377,10 +377,12 @@ static noinline __kprobes int vmalloc_fault(unsigned long address) + if (pgd_none(*pgd_ref)) + return -1; + +- if (pgd_none(*pgd)) ++ if (pgd_none(*pgd)) { + set_pgd(pgd, *pgd_ref); +- else ++ arch_flush_lazy_mmu_mode(); ++ } else { + BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref)); ++ } + + /* + * Below here mismatches are bugs because these lower tables +diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c +index 5cb8e27..cf7fe36 100644 +--- a/arch/x86/xen/mmu.c ++++ b/arch/x86/xen/mmu.c +@@ -2076,6 +2076,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = { + .lazy_mode = { + .enter = paravirt_enter_lazy_mmu, + .leave = xen_leave_lazy_mmu, ++ .flush = paravirt_flush_lazy_mmu, + }, + + .set_fixmap = xen_set_fixmap, +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index a135c61..99a7855 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -72,7 +72,7 @@ int i915_gem_init_aliasing_ppgtt(struct drm_device *dev) + /* ppgtt PDEs reside in the global gtt pagetable, which has 512*1024 + * entries. For aliasing ppgtt support we just steal them at the end for + * now. */ +- first_pd_entry_in_global_pt = 512*1024 - I915_PPGTT_PD_ENTRIES; ++ first_pd_entry_in_global_pt = dev_priv->mm.gtt->gtt_total_entries - I915_PPGTT_PD_ENTRIES; + + ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); + if (!ppgtt) +diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c +index 3234224..b8e6463 100644 +--- a/drivers/gpu/drm/udl/udl_connector.c ++++ b/drivers/gpu/drm/udl/udl_connector.c +@@ -61,6 +61,10 @@ static int udl_get_modes(struct drm_connector *connector) + int ret; + + edid = (struct edid *)udl_get_edid(udl); ++ if (!edid) { ++ drm_mode_connector_update_edid_property(connector, NULL); ++ return 0; ++ } + + connector->display_info.raw_edid = (char *)edid; + +diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c +index f2f482b..76afcb4 100644 +--- a/drivers/mtd/mtdchar.c ++++ b/drivers/mtd/mtdchar.c +@@ -1123,6 +1123,33 @@ static unsigned long mtdchar_get_unmapped_area(struct file *file, + } + #endif + ++static inline unsigned long get_vm_size(struct vm_area_struct *vma) ++{ ++ return vma->vm_end - vma->vm_start; ++} ++ ++static inline resource_size_t get_vm_offset(struct vm_area_struct *vma) ++{ ++ return (resource_size_t) vma->vm_pgoff << PAGE_SHIFT; ++} ++ ++/* ++ * Set a new vm offset. ++ * ++ * Verify that the incoming offset really works as a page offset, ++ * and that the offset and size fit in a resource_size_t. ++ */ ++static inline int set_vm_offset(struct vm_area_struct *vma, resource_size_t off) ++{ ++ pgoff_t pgoff = off >> PAGE_SHIFT; ++ if (off != (resource_size_t) pgoff << PAGE_SHIFT) ++ return -EINVAL; ++ if (off + get_vm_size(vma) - 1 < off) ++ return -EINVAL; ++ vma->vm_pgoff = pgoff; ++ return 0; ++} ++ + /* + * set up a mapping for shared memory segments + */ +@@ -1132,20 +1159,33 @@ static int mtdchar_mmap(struct file *file, struct vm_area_struct *vma) + struct mtd_file_info *mfi = file->private_data; + struct mtd_info *mtd = mfi->mtd; + struct map_info *map = mtd->priv; +- unsigned long start; +- unsigned long off; +- u32 len; +- +- if (mtd->type == MTD_RAM || mtd->type == MTD_ROM) { +- off = vma->vm_pgoff << PAGE_SHIFT; ++ resource_size_t start, off; ++ unsigned long len, vma_len; ++ ++ /* This is broken because it assumes the MTD device is map-based ++ and that mtd->priv is a valid struct map_info. It should be ++ replaced with something that uses the mtd_get_unmapped_area() ++ operation properly. */ ++ if (0 /*mtd->type == MTD_RAM || mtd->type == MTD_ROM*/) { ++ off = get_vm_offset(vma); + start = map->phys; + len = PAGE_ALIGN((start & ~PAGE_MASK) + map->size); + start &= PAGE_MASK; +- if ((vma->vm_end - vma->vm_start + off) > len) ++ vma_len = get_vm_size(vma); ++ ++ /* Overflow in off+len? */ ++ if (vma_len + off < off) ++ return -EINVAL; ++ /* Does it fit in the mapping? */ ++ if (vma_len + off > len) + return -EINVAL; + + off += start; +- vma->vm_pgoff = off >> PAGE_SHIFT; ++ /* Did that overflow? */ ++ if (off < start) ++ return -EINVAL; ++ if (set_vm_offset(vma, off) < 0) ++ return -EINVAL; + vma->vm_flags |= VM_IO | VM_RESERVED; + + #ifdef pgprot_noncached +diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c +index df49ce2..978af21 100644 +--- a/drivers/net/ethernet/realtek/r8169.c ++++ b/drivers/net/ethernet/realtek/r8169.c +@@ -3483,6 +3483,30 @@ static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp) + } + } + ++static void rtl_speed_down(struct rtl8169_private *tp) ++{ ++ u32 adv; ++ int lpa; ++ ++ rtl_writephy(tp, 0x1f, 0x0000); ++ lpa = rtl_readphy(tp, MII_LPA); ++ ++ if (lpa & (LPA_10HALF | LPA_10FULL)) ++ adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full; ++ else if (lpa & (LPA_100HALF | LPA_100FULL)) ++ adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | ++ ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full; ++ else ++ adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | ++ ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | ++ (tp->mii.supports_gmii ? ++ ADVERTISED_1000baseT_Half | ++ ADVERTISED_1000baseT_Full : 0); ++ ++ rtl8169_set_speed(tp->dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL, ++ adv); ++} ++ + static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) + { + void __iomem *ioaddr = tp->mmio_addr; +@@ -3508,9 +3532,7 @@ static bool rtl_wol_pll_power_down(struct rtl8169_private *tp) + if (!(__rtl8169_get_wol(tp) & WAKE_ANY)) + return false; + +- rtl_writephy(tp, 0x1f, 0x0000); +- rtl_writephy(tp, MII_BMCR, 0x0000); +- ++ rtl_speed_down(tp); + rtl_wol_suspend_quirk(tp); + + return true; +diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c +index 101b28e..58e6183 100644 +--- a/drivers/scsi/libsas/sas_expander.c ++++ b/drivers/scsi/libsas/sas_expander.c +@@ -235,6 +235,17 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) + linkrate = phy->linkrate; + memcpy(sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE); + ++ /* Handle vacant phy - rest of dr data is not valid so skip it */ ++ if (phy->phy_state == PHY_VACANT) { ++ memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE); ++ phy->attached_dev_type = NO_DEVICE; ++ if (!test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)) { ++ phy->phy_id = phy_id; ++ goto skip; ++ } else ++ goto out; ++ } ++ + phy->attached_dev_type = to_dev_type(dr); + if (test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)) + goto out; +@@ -272,6 +283,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) + phy->phy->maximum_linkrate = dr->pmax_linkrate; + phy->phy->negotiated_linkrate = phy->linkrate; + ++ skip: + if (new_phy) + if (sas_phy_add(phy->phy)) { + sas_phy_free(phy->phy); +diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c +index f30e124..aa3c106 100644 +--- a/drivers/target/target_core_alua.c ++++ b/drivers/target/target_core_alua.c +@@ -392,6 +392,7 @@ static inline int core_alua_state_standby( + case REPORT_LUNS: + case RECEIVE_DIAGNOSTIC: + case SEND_DIAGNOSTIC: ++ return 0; + case MAINTENANCE_IN: + switch (cdb[1]) { + case MI_REPORT_TARGET_PGS: +@@ -434,6 +435,7 @@ static inline int core_alua_state_unavailable( + switch (cdb[0]) { + case INQUIRY: + case REPORT_LUNS: ++ return 0; + case MAINTENANCE_IN: + switch (cdb[1]) { + case MI_REPORT_TARGET_PGS: +@@ -474,6 +476,7 @@ static inline int core_alua_state_transition( + switch (cdb[0]) { + case INQUIRY: + case REPORT_LUNS: ++ return 0; + case MAINTENANCE_IN: + switch (cdb[1]) { + case MI_REPORT_TARGET_PGS: +diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c +index f771e9f..9cc574c 100644 +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -1576,14 +1576,24 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, + } + break; + case Opt_blank_pass: +- vol->password = NULL; +- break; +- case Opt_pass: + /* passwords have to be handled differently + * to allow the character used for deliminator + * to be passed within them + */ + ++ /* ++ * Check if this is a case where the password ++ * starts with a delimiter ++ */ ++ tmp_end = strchr(data, '='); ++ tmp_end++; ++ if (!(tmp_end < end && tmp_end[1] == delim)) { ++ /* No it is not. Set the password to NULL */ ++ vol->password = NULL; ++ break; ++ } ++ /* Yes it is. Drop down to Opt_pass below.*/ ++ case Opt_pass: + /* Obtain the value string */ + value = strchr(data, '='); + value++; +diff --git a/fs/inode.c b/fs/inode.c +index 9f4f5fe..8de457e 100644 +--- a/fs/inode.c ++++ b/fs/inode.c +@@ -705,7 +705,7 @@ void prune_icache_sb(struct super_block *sb, int nr_to_scan) + * inode to the back of the list so we don't spin on it. + */ + if (!spin_trylock(&inode->i_lock)) { +- list_move_tail(&inode->i_lru, &sb->s_inode_lru); ++ list_move(&inode->i_lru, &sb->s_inode_lru); + continue; + } + +diff --git a/kernel/sched/clock.c b/kernel/sched/clock.c +index c685e31..c3ae144 100644 +--- a/kernel/sched/clock.c ++++ b/kernel/sched/clock.c +@@ -176,10 +176,36 @@ static u64 sched_clock_remote(struct sched_clock_data *scd) + u64 this_clock, remote_clock; + u64 *ptr, old_val, val; + ++#if BITS_PER_LONG != 64 ++again: ++ /* ++ * Careful here: The local and the remote clock values need to ++ * be read out atomic as we need to compare the values and ++ * then update either the local or the remote side. So the ++ * cmpxchg64 below only protects one readout. ++ * ++ * We must reread via sched_clock_local() in the retry case on ++ * 32bit as an NMI could use sched_clock_local() via the ++ * tracer and hit between the readout of ++ * the low32bit and the high 32bit portion. ++ */ ++ this_clock = sched_clock_local(my_scd); ++ /* ++ * We must enforce atomic readout on 32bit, otherwise the ++ * update on the remote cpu can hit inbetween the readout of ++ * the low32bit and the high 32bit portion. ++ */ ++ remote_clock = cmpxchg64(&scd->clock, 0, 0); ++#else ++ /* ++ * On 64bit the read of [my]scd->clock is atomic versus the ++ * update, so we can avoid the above 32bit dance. ++ */ + sched_clock_local(my_scd); + again: + this_clock = my_scd->clock; + remote_clock = scd->clock; ++#endif + + /* + * Use the opportunity that we have both locks +diff --git a/kernel/sys.c b/kernel/sys.c +index b0003db..6a74b83 100644 +--- a/kernel/sys.c ++++ b/kernel/sys.c +@@ -320,7 +320,6 @@ void kernel_restart_prepare(char *cmd) + system_state = SYSTEM_RESTART; + usermodehelper_disable(); + device_shutdown(); +- syscore_shutdown(); + } + + /** +@@ -366,6 +365,7 @@ void kernel_restart(char *cmd) + { + kernel_restart_prepare(cmd); + disable_nonboot_cpus(); ++ syscore_shutdown(); + if (!cmd) + printk(KERN_EMERG "Restarting system.\n"); + else +@@ -391,6 +391,7 @@ static void kernel_shutdown_prepare(enum system_states state) + void kernel_halt(void) + { + kernel_shutdown_prepare(SYSTEM_HALT); ++ disable_nonboot_cpus(); + syscore_shutdown(); + printk(KERN_EMERG "System halted.\n"); + kmsg_dump(KMSG_DUMP_HALT); +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index e539dfa..a3c1dd9 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -642,7 +642,6 @@ int ftrace_profile_pages_init(struct ftrace_profile_stat *stat) + free_page(tmp); + } + +- free_page((unsigned long)stat->pages); + stat->pages = NULL; + stat->start = NULL; + +diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c +index c91fb2f..77758542 100644 +--- a/sound/soc/codecs/wm8903.c ++++ b/sound/soc/codecs/wm8903.c +@@ -1082,6 +1082,8 @@ static const struct snd_soc_dapm_route wm8903_intercon[] = { + { "ROP", NULL, "Right Speaker PGA" }, + { "RON", NULL, "Right Speaker PGA" }, + ++ { "Charge Pump", NULL, "CLK_DSP" }, ++ + { "Left Headphone Output PGA", NULL, "Charge Pump" }, + { "Right Headphone Output PGA", NULL, "Charge Pump" }, + { "Left Line Output PGA", NULL, "Charge Pump" }, +diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c +index 38a607a..fb95069 100644 +--- a/sound/usb/mixer_quirks.c ++++ b/sound/usb/mixer_quirks.c +@@ -396,7 +396,7 @@ static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol, + else + ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, +- 0, cpu_to_le16(wIndex), ++ 0, wIndex, + &tmp, sizeof(tmp), 1000); + up_read(&mixer->chip->shutdown_rwsem); + +@@ -427,7 +427,7 @@ static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol, + else + ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, +- cpu_to_le16(wValue), cpu_to_le16(wIndex), ++ wValue, wIndex, + NULL, 0, 1000); + up_read(&mixer->chip->shutdown_rwsem); + +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index c46171a..b7fa802 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -486,7 +486,7 @@ static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev) + { + int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + 0xaf, USB_TYPE_VENDOR | USB_RECIP_DEVICE, +- cpu_to_le16(1), 0, NULL, 0, 1000); ++ 1, 0, NULL, 0, 1000); + + if (ret < 0) + return ret; diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.41-42.patch b/patch/kernel/sun8i-default/0001-patch-3.4.41-42.patch new file mode 100644 index 000000000..c5f4c6cc8 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.41-42.patch @@ -0,0 +1,1119 @@ +diff --git a/Makefile b/Makefile +index 90c3a6f..35c00db 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 41 ++SUBLEVEL = 42 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c +index dd3d591..48bc3c0 100644 +--- a/arch/arm/mm/cache-feroceon-l2.c ++++ b/arch/arm/mm/cache-feroceon-l2.c +@@ -343,6 +343,7 @@ void __init feroceon_l2_init(int __l2_wt_override) + outer_cache.inv_range = feroceon_l2_inv_range; + outer_cache.clean_range = feroceon_l2_clean_range; + outer_cache.flush_range = feroceon_l2_flush_range; ++ outer_cache.inv_all = l2_inv_all; + + enable_l2(); + +diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S +index cb941ae..aeeb126 100644 +--- a/arch/arm/mm/proc-arm920.S ++++ b/arch/arm/mm/proc-arm920.S +@@ -383,7 +383,7 @@ ENTRY(cpu_arm920_set_pte_ext) + /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */ + .globl cpu_arm920_suspend_size + .equ cpu_arm920_suspend_size, 4 * 3 +-#ifdef CONFIG_PM_SLEEP ++#ifdef CONFIG_ARM_CPU_SUSPEND + ENTRY(cpu_arm920_do_suspend) + stmfd sp!, {r4 - r6, lr} + mrc p15, 0, r4, c13, c0, 0 @ PID +diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S +index 820259b..ee29dc4 100644 +--- a/arch/arm/mm/proc-arm926.S ++++ b/arch/arm/mm/proc-arm926.S +@@ -398,7 +398,7 @@ ENTRY(cpu_arm926_set_pte_ext) + /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */ + .globl cpu_arm926_suspend_size + .equ cpu_arm926_suspend_size, 4 * 3 +-#ifdef CONFIG_PM_SLEEP ++#ifdef CONFIG_ARM_CPU_SUSPEND + ENTRY(cpu_arm926_do_suspend) + stmfd sp!, {r4 - r6, lr} + mrc p15, 0, r4, c13, c0, 0 @ PID +diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S +index 3aa0da1..d92dfd0 100644 +--- a/arch/arm/mm/proc-sa1100.S ++++ b/arch/arm/mm/proc-sa1100.S +@@ -172,7 +172,7 @@ ENTRY(cpu_sa1100_set_pte_ext) + + .globl cpu_sa1100_suspend_size + .equ cpu_sa1100_suspend_size, 4 * 3 +-#ifdef CONFIG_PM_SLEEP ++#ifdef CONFIG_ARM_CPU_SUSPEND + ENTRY(cpu_sa1100_do_suspend) + stmfd sp!, {r4 - r6, lr} + mrc p15, 0, r4, c3, c0, 0 @ domain ID +diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S +index 5900cd5..897486c 100644 +--- a/arch/arm/mm/proc-v6.S ++++ b/arch/arm/mm/proc-v6.S +@@ -132,7 +132,7 @@ ENTRY(cpu_v6_set_pte_ext) + /* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */ + .globl cpu_v6_suspend_size + .equ cpu_v6_suspend_size, 4 * 6 +-#ifdef CONFIG_PM_SLEEP ++#ifdef CONFIG_ARM_CPU_SUSPEND + ENTRY(cpu_v6_do_suspend) + stmfd sp!, {r4 - r9, lr} + mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID +diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S +index b0d5786..a2d1e86 100644 +--- a/arch/arm/mm/proc-xsc3.S ++++ b/arch/arm/mm/proc-xsc3.S +@@ -410,7 +410,7 @@ ENTRY(cpu_xsc3_set_pte_ext) + + .globl cpu_xsc3_suspend_size + .equ cpu_xsc3_suspend_size, 4 * 6 +-#ifdef CONFIG_PM_SLEEP ++#ifdef CONFIG_ARM_CPU_SUSPEND + ENTRY(cpu_xsc3_do_suspend) + stmfd sp!, {r4 - r9, lr} + mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode +diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S +index 4ffebaa..9882153 100644 +--- a/arch/arm/mm/proc-xscale.S ++++ b/arch/arm/mm/proc-xscale.S +@@ -524,7 +524,7 @@ ENTRY(cpu_xscale_set_pte_ext) + + .globl cpu_xscale_suspend_size + .equ cpu_xscale_suspend_size, 4 * 6 +-#ifdef CONFIG_PM_SLEEP ++#ifdef CONFIG_ARM_CPU_SUSPEND + ENTRY(cpu_xscale_do_suspend) + stmfd sp!, {r4 - r9, lr} + mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode +diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h +index e216ba0..d57eacb 100644 +--- a/arch/x86/include/asm/kvm_host.h ++++ b/arch/x86/include/asm/kvm_host.h +@@ -407,8 +407,8 @@ struct kvm_vcpu_arch { + gpa_t time; + struct pvclock_vcpu_time_info hv_clock; + unsigned int hw_tsc_khz; +- unsigned int time_offset; +- struct page *time_page; ++ struct gfn_to_hva_cache pv_time; ++ bool pv_time_enabled; + + struct { + u64 msr_val; +diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c +index 26b3e2f..268b245 100644 +--- a/arch/x86/kernel/cpu/perf_event_intel.c ++++ b/arch/x86/kernel/cpu/perf_event_intel.c +@@ -126,8 +126,14 @@ static struct event_constraint intel_gen_event_constraints[] __read_mostly = + }; + + static struct extra_reg intel_snb_extra_regs[] __read_mostly = { +- INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3fffffffffull, RSP_0), +- INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3fffffffffull, RSP_1), ++ INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3f807f8fffull, RSP_0), ++ INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3f807f8fffull, RSP_1), ++ EVENT_EXTRA_END ++}; ++ ++static struct extra_reg intel_snbep_extra_regs[] __read_mostly = { ++ INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3fffff8fffull, RSP_0), ++ INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3fffff8fffull, RSP_1), + EVENT_EXTRA_END + }; + +@@ -1851,7 +1857,10 @@ __init int intel_pmu_init(void) + + x86_pmu.event_constraints = intel_snb_event_constraints; + x86_pmu.pebs_constraints = intel_snb_pebs_event_constraints; +- x86_pmu.extra_regs = intel_snb_extra_regs; ++ if (boot_cpu_data.x86_model == 45) ++ x86_pmu.extra_regs = intel_snbep_extra_regs; ++ else ++ x86_pmu.extra_regs = intel_snb_extra_regs; + /* all extra regs are per-cpu when HT is on */ + x86_pmu.er_flags |= ERF_HAS_RSP_1; + x86_pmu.er_flags |= ERF_NO_HT_SHARING; +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index e28fb97..b27b452 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -1114,7 +1114,6 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) + { + unsigned long flags; + struct kvm_vcpu_arch *vcpu = &v->arch; +- void *shared_kaddr; + unsigned long this_tsc_khz; + s64 kernel_ns, max_kernel_ns; + u64 tsc_timestamp; +@@ -1150,7 +1149,7 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) + + local_irq_restore(flags); + +- if (!vcpu->time_page) ++ if (!vcpu->pv_time_enabled) + return 0; + + /* +@@ -1208,14 +1207,9 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) + */ + vcpu->hv_clock.version += 2; + +- shared_kaddr = kmap_atomic(vcpu->time_page); +- +- memcpy(shared_kaddr + vcpu->time_offset, &vcpu->hv_clock, +- sizeof(vcpu->hv_clock)); +- +- kunmap_atomic(shared_kaddr); +- +- mark_page_dirty(v->kvm, vcpu->time >> PAGE_SHIFT); ++ kvm_write_guest_cached(v->kvm, &vcpu->pv_time, ++ &vcpu->hv_clock, ++ sizeof(vcpu->hv_clock)); + return 0; + } + +@@ -1494,7 +1488,8 @@ static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data) + return 0; + } + +- if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.apf.data, gpa)) ++ if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.apf.data, gpa, ++ sizeof(u32))) + return 1; + + vcpu->arch.apf.send_user_only = !(data & KVM_ASYNC_PF_SEND_ALWAYS); +@@ -1504,10 +1499,7 @@ static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data) + + static void kvmclock_reset(struct kvm_vcpu *vcpu) + { +- if (vcpu->arch.time_page) { +- kvm_release_page_dirty(vcpu->arch.time_page); +- vcpu->arch.time_page = NULL; +- } ++ vcpu->arch.pv_time_enabled = false; + } + + static void accumulate_steal_time(struct kvm_vcpu *vcpu) +@@ -1602,6 +1594,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) + break; + case MSR_KVM_SYSTEM_TIME_NEW: + case MSR_KVM_SYSTEM_TIME: { ++ u64 gpa_offset; + kvmclock_reset(vcpu); + + vcpu->arch.time = data; +@@ -1611,16 +1604,14 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) + if (!(data & 1)) + break; + +- /* ...but clean it before doing the actual write */ +- vcpu->arch.time_offset = data & ~(PAGE_MASK | 1); ++ gpa_offset = data & ~(PAGE_MASK | 1); + +- vcpu->arch.time_page = +- gfn_to_page(vcpu->kvm, data >> PAGE_SHIFT); +- +- if (is_error_page(vcpu->arch.time_page)) { +- kvm_release_page_clean(vcpu->arch.time_page); +- vcpu->arch.time_page = NULL; +- } ++ if (kvm_gfn_to_hva_cache_init(vcpu->kvm, ++ &vcpu->arch.pv_time, data & ~1ULL, ++ sizeof(struct pvclock_vcpu_time_info))) ++ vcpu->arch.pv_time_enabled = false; ++ else ++ vcpu->arch.pv_time_enabled = true; + break; + } + case MSR_KVM_ASYNC_PF_EN: +@@ -1636,7 +1627,8 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) + return 1; + + if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.st.stime, +- data & KVM_STEAL_VALID_BITS)) ++ data & KVM_STEAL_VALID_BITS, ++ sizeof(struct kvm_steal_time))) + return 1; + + vcpu->arch.st.msr_val = data; +@@ -6167,6 +6159,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) + if (!zalloc_cpumask_var(&vcpu->arch.wbinvd_dirty_mask, GFP_KERNEL)) + goto fail_free_mce_banks; + ++ vcpu->arch.pv_time_enabled = false; + kvm_async_pf_hash_reset(vcpu); + kvm_pmu_init(vcpu); + +diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c +index ef5356c..0262210 100644 +--- a/crypto/algif_hash.c ++++ b/crypto/algif_hash.c +@@ -161,6 +161,8 @@ static int hash_recvmsg(struct kiocb *unused, struct socket *sock, + else if (len < ds) + msg->msg_flags |= MSG_TRUNC; + ++ msg->msg_namelen = 0; ++ + lock_sock(sk); + if (ctx->more) { + ctx->more = 0; +diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c +index 6a6dfc0..a1c4f0a 100644 +--- a/crypto/algif_skcipher.c ++++ b/crypto/algif_skcipher.c +@@ -432,6 +432,7 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock, + long copied = 0; + + lock_sock(sk); ++ msg->msg_namelen = 0; + for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0; + iovlen--, iov++) { + unsigned long seglen = iov->iov_len; +diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c +index dfd7876..0ff5c2e 100644 +--- a/drivers/char/hpet.c ++++ b/drivers/char/hpet.c +@@ -373,26 +373,14 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma) + struct hpet_dev *devp; + unsigned long addr; + +- if (((vma->vm_end - vma->vm_start) != PAGE_SIZE) || vma->vm_pgoff) +- return -EINVAL; +- + devp = file->private_data; + addr = devp->hd_hpets->hp_hpet_phys; + + if (addr & (PAGE_SIZE - 1)) + return -ENOSYS; + +- vma->vm_flags |= VM_IO; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); +- +- if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, +- PAGE_SIZE, vma->vm_page_prot)) { +- printk(KERN_ERR "%s: io_remap_pfn_range failed\n", +- __func__); +- return -EAGAIN; +- } +- +- return 0; ++ return vm_iomap_memory(vma, addr, PAGE_SIZE); + #else + return -ENOSYS; + #endif +diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c +index 58434e8..37fe246 100644 +--- a/drivers/gpu/vga/vga_switcheroo.c ++++ b/drivers/gpu/vga/vga_switcheroo.c +@@ -26,6 +26,7 @@ + #include + + #include ++#include + #include + + struct vga_switcheroo_client { +@@ -256,8 +257,10 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client) + + if (new_client->fb_info) { + struct fb_event event; ++ console_lock(); + event.info = new_client->fb_info; + fb_notifier_call_chain(FB_EVENT_REMAP_ALL_CONSOLE, &event); ++ console_unlock(); + } + + ret = vgasr_priv.handler->switchto(new_client->id); +diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c +index 76afcb4..6e3d6dc 100644 +--- a/drivers/mtd/mtdchar.c ++++ b/drivers/mtd/mtdchar.c +@@ -1159,45 +1159,17 @@ static int mtdchar_mmap(struct file *file, struct vm_area_struct *vma) + struct mtd_file_info *mfi = file->private_data; + struct mtd_info *mtd = mfi->mtd; + struct map_info *map = mtd->priv; +- resource_size_t start, off; +- unsigned long len, vma_len; + + /* This is broken because it assumes the MTD device is map-based + and that mtd->priv is a valid struct map_info. It should be + replaced with something that uses the mtd_get_unmapped_area() + operation properly. */ + if (0 /*mtd->type == MTD_RAM || mtd->type == MTD_ROM*/) { +- off = get_vm_offset(vma); +- start = map->phys; +- len = PAGE_ALIGN((start & ~PAGE_MASK) + map->size); +- start &= PAGE_MASK; +- vma_len = get_vm_size(vma); +- +- /* Overflow in off+len? */ +- if (vma_len + off < off) +- return -EINVAL; +- /* Does it fit in the mapping? */ +- if (vma_len + off > len) +- return -EINVAL; +- +- off += start; +- /* Did that overflow? */ +- if (off < start) +- return -EINVAL; +- if (set_vm_offset(vma, off) < 0) +- return -EINVAL; +- vma->vm_flags |= VM_IO | VM_RESERVED; +- + #ifdef pgprot_noncached +- if (file->f_flags & O_DSYNC || off >= __pa(high_memory)) ++ if (file->f_flags & O_DSYNC || map->phys >= __pa(high_memory)) + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + #endif +- if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, +- vma->vm_end - vma->vm_start, +- vma->vm_page_prot)) +- return -EAGAIN; +- +- return 0; ++ return vm_iomap_memory(vma, map->phys, map->size); + } + return -ENOSYS; + #else +diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c +index f2683eb..c505b55 100644 +--- a/drivers/net/can/sja1000/sja1000_of_platform.c ++++ b/drivers/net/can/sja1000/sja1000_of_platform.c +@@ -94,8 +94,8 @@ static int __devinit sja1000_ofp_probe(struct platform_device *ofdev) + struct net_device *dev; + struct sja1000_priv *priv; + struct resource res; +- const u32 *prop; +- int err, irq, res_size, prop_size; ++ u32 prop; ++ int err, irq, res_size; + void __iomem *base; + + err = of_address_to_resource(np, 0, &res); +@@ -136,27 +136,27 @@ static int __devinit sja1000_ofp_probe(struct platform_device *ofdev) + priv->read_reg = sja1000_ofp_read_reg; + priv->write_reg = sja1000_ofp_write_reg; + +- prop = of_get_property(np, "nxp,external-clock-frequency", &prop_size); +- if (prop && (prop_size == sizeof(u32))) +- priv->can.clock.freq = *prop / 2; ++ err = of_property_read_u32(np, "nxp,external-clock-frequency", &prop); ++ if (!err) ++ priv->can.clock.freq = prop / 2; + else + priv->can.clock.freq = SJA1000_OFP_CAN_CLOCK; /* default */ + +- prop = of_get_property(np, "nxp,tx-output-mode", &prop_size); +- if (prop && (prop_size == sizeof(u32))) +- priv->ocr |= *prop & OCR_MODE_MASK; ++ err = of_property_read_u32(np, "nxp,tx-output-mode", &prop); ++ if (!err) ++ priv->ocr |= prop & OCR_MODE_MASK; + else + priv->ocr |= OCR_MODE_NORMAL; /* default */ + +- prop = of_get_property(np, "nxp,tx-output-config", &prop_size); +- if (prop && (prop_size == sizeof(u32))) +- priv->ocr |= (*prop << OCR_TX_SHIFT) & OCR_TX_MASK; ++ err = of_property_read_u32(np, "nxp,tx-output-config", &prop); ++ if (!err) ++ priv->ocr |= (prop << OCR_TX_SHIFT) & OCR_TX_MASK; + else + priv->ocr |= OCR_TX0_PULLDOWN; /* default */ + +- prop = of_get_property(np, "nxp,clock-out-frequency", &prop_size); +- if (prop && (prop_size == sizeof(u32)) && *prop) { +- u32 divider = priv->can.clock.freq * 2 / *prop; ++ err = of_property_read_u32(np, "nxp,clock-out-frequency", &prop); ++ if (!err && prop) { ++ u32 divider = priv->can.clock.freq * 2 / prop; + + if (divider > 1) + priv->cdr |= divider / 2 - 1; +@@ -166,8 +166,7 @@ static int __devinit sja1000_ofp_probe(struct platform_device *ofdev) + priv->cdr |= CDR_CLK_OFF; /* default */ + } + +- prop = of_get_property(np, "nxp,no-comparator-bypass", NULL); +- if (!prop) ++ if (!of_property_read_bool(np, "nxp,no-comparator-bypass")) + priv->cdr |= CDR_CBP; /* default */ + + priv->irq_flags = IRQF_SHARED; +diff --git a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h +index 06b3f0d..c16bea4 100644 +--- a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h ++++ b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h +@@ -648,7 +648,7 @@ static const u32 ar9580_1p0_mac_core[][2] = { + {0x00008258, 0x00000000}, + {0x0000825c, 0x40000000}, + {0x00008260, 0x00080922}, +- {0x00008264, 0x9bc00010}, ++ {0x00008264, 0x9d400010}, + {0x00008268, 0xffffffff}, + {0x0000826c, 0x0000ffff}, + {0x00008270, 0x00000000}, +diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c +index de5ee15..41c5237 100644 +--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c ++++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c +@@ -771,7 +771,7 @@ static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv) + * required version. + */ + if (priv->fw_version_major != MAJOR_VERSION_REQ || +- priv->fw_version_minor != MINOR_VERSION_REQ) { ++ priv->fw_version_minor < MINOR_VERSION_REQ) { + dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n", + MAJOR_VERSION_REQ, MINOR_VERSION_REQ); + return -EINVAL; +diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c +index 6be2f73..4ce3e1f 100644 +--- a/drivers/net/wireless/b43/phy_n.c ++++ b/drivers/net/wireless/b43/phy_n.c +@@ -4582,7 +4582,8 @@ static void b43_nphy_pmu_spur_avoid(struct b43_wldev *dev, bool avoid) + #endif + #ifdef CONFIG_B43_SSB + case B43_BUS_SSB: +- /* FIXME */ ++ ssb_pmu_spuravoid_pllupdate(&dev->dev->sdev->bus->chipco, ++ avoid); + break; + #endif + } +diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c +index b58fef7..1fb9b22 100644 +--- a/drivers/ssb/driver_chipcommon_pmu.c ++++ b/drivers/ssb/driver_chipcommon_pmu.c +@@ -645,3 +645,32 @@ u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc) + return 0; + } + } ++ ++void ssb_pmu_spuravoid_pllupdate(struct ssb_chipcommon *cc, int spuravoid) ++{ ++ u32 pmu_ctl = 0; ++ ++ switch (cc->dev->bus->chip_id) { ++ case 0x4322: ++ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL0, 0x11100070); ++ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL1, 0x1014140a); ++ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL5, 0x88888854); ++ if (spuravoid == 1) ++ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05201828); ++ else ++ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05001828); ++ pmu_ctl = SSB_CHIPCO_PMU_CTL_PLL_UPD; ++ break; ++ case 43222: ++ /* TODO: BCM43222 requires updating PLLs too */ ++ return; ++ default: ++ ssb_printk(KERN_ERR PFX ++ "Unknown spuravoidance settings for chip 0x%04X, not changing PLL\n", ++ cc->dev->bus->chip_id); ++ return; ++ } ++ ++ chipco_set32(cc, SSB_CHIPCO_PMU_CTL, pmu_ctl); ++} ++EXPORT_SYMBOL_GPL(ssb_pmu_spuravoid_pllupdate); +diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c +index 5bf163e..18ded2d 100644 +--- a/drivers/video/console/fbcon.c ++++ b/drivers/video/console/fbcon.c +@@ -842,6 +842,8 @@ static void con2fb_init_display(struct vc_data *vc, struct fb_info *info, + * + * Maps a virtual console @unit to a frame buffer device + * @newidx. ++ * ++ * This should be called with the console lock held. + */ + static int set_con2fb_map(int unit, int newidx, int user) + { +@@ -859,7 +861,7 @@ static int set_con2fb_map(int unit, int newidx, int user) + + if (!search_for_mapped_con() || !con_is_bound(&fb_con)) { + info_idx = newidx; +- return fbcon_takeover(0); ++ return do_fbcon_takeover(0); + } + + if (oldidx != -1) +@@ -867,7 +869,6 @@ static int set_con2fb_map(int unit, int newidx, int user) + + found = search_fb_in_map(newidx); + +- console_lock(); + con2fb_map[unit] = newidx; + if (!err && !found) + err = con2fb_acquire_newinfo(vc, info, unit, oldidx); +@@ -894,7 +895,6 @@ static int set_con2fb_map(int unit, int newidx, int user) + if (!search_fb_in_map(info_idx)) + info_idx = newidx; + +- console_unlock(); + return err; + } + +@@ -3025,6 +3025,7 @@ static inline int fbcon_unbind(void) + } + #endif /* CONFIG_VT_HW_CONSOLE_BINDING */ + ++/* called with console_lock held */ + static int fbcon_fb_unbind(int idx) + { + int i, new_idx = -1, ret = 0; +@@ -3051,6 +3052,7 @@ static int fbcon_fb_unbind(int idx) + return ret; + } + ++/* called with console_lock held */ + static int fbcon_fb_unregistered(struct fb_info *info) + { + int i, idx; +@@ -3088,6 +3090,7 @@ static int fbcon_fb_unregistered(struct fb_info *info) + return 0; + } + ++/* called with console_lock held */ + static void fbcon_remap_all(int idx) + { + int i; +@@ -3132,6 +3135,7 @@ static inline void fbcon_select_primary(struct fb_info *info) + } + #endif /* CONFIG_FRAMEBUFFER_DETECT_PRIMARY */ + ++/* called with console_lock held */ + static int fbcon_fb_registered(struct fb_info *info) + { + int ret = 0, i, idx; +@@ -3284,6 +3288,7 @@ static int fbcon_event_notify(struct notifier_block *self, + ret = fbcon_fb_unregistered(info); + break; + case FB_EVENT_SET_CONSOLE_MAP: ++ /* called with console lock held */ + con2fb = event->data; + ret = set_con2fb_map(con2fb->console - 1, + con2fb->framebuffer, 1); +diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c +index 90f1315..5641a22 100644 +--- a/drivers/video/fbmem.c ++++ b/drivers/video/fbmem.c +@@ -1168,8 +1168,10 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, + event.data = &con2fb; + if (!lock_fb_info(info)) + return -ENODEV; ++ console_lock(); + event.info = info; + ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event); ++ console_unlock(); + unlock_fb_info(info); + break; + case FBIOBLANK: +@@ -1362,15 +1364,12 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) + { + struct fb_info *info = file_fb_info(file); + struct fb_ops *fb; +- unsigned long off; ++ unsigned long mmio_pgoff; + unsigned long start; + u32 len; + + if (!info) + return -ENODEV; +- if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) +- return -EINVAL; +- off = vma->vm_pgoff << PAGE_SHIFT; + fb = info->fbops; + if (!fb) + return -ENODEV; +@@ -1382,33 +1381,24 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) + return res; + } + +- /* frame buffer memory */ ++ /* ++ * Ugh. This can be either the frame buffer mapping, or ++ * if pgoff points past it, the mmio mapping. ++ */ + start = info->fix.smem_start; +- len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len); +- if (off >= len) { +- /* memory mapped io */ +- off -= len; +- if (info->var.accel_flags) { +- mutex_unlock(&info->mm_lock); +- return -EINVAL; +- } ++ len = info->fix.smem_len; ++ mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT; ++ if (vma->vm_pgoff >= mmio_pgoff) { ++ vma->vm_pgoff -= mmio_pgoff; + start = info->fix.mmio_start; +- len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); ++ len = info->fix.mmio_len; + } + mutex_unlock(&info->mm_lock); +- start &= PAGE_MASK; +- if ((vma->vm_end - vma->vm_start + off) > len) +- return -EINVAL; +- off += start; +- vma->vm_pgoff = off >> PAGE_SHIFT; +- /* This is an IO map - tell maydump to skip this VMA */ +- vma->vm_flags |= VM_IO | VM_RESERVED; ++ + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); +- fb_pgprotect(file, vma, off); +- if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, +- vma->vm_end - vma->vm_start, vma->vm_page_prot)) +- return -EAGAIN; +- return 0; ++ fb_pgprotect(file, vma, start); ++ ++ return vm_iomap_memory(vma, start, len); + } + + static int +diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c +index dce89da..3ef7f38 100644 +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -315,6 +315,7 @@ static noinline int overwrite_item(struct btrfs_trans_handle *trans, + unsigned long src_ptr; + unsigned long dst_ptr; + int overwrite_root = 0; ++ bool inode_item = key->type == BTRFS_INODE_ITEM_KEY; + + if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) + overwrite_root = 1; +@@ -324,6 +325,9 @@ static noinline int overwrite_item(struct btrfs_trans_handle *trans, + + /* look for the key in the destination tree */ + ret = btrfs_search_slot(NULL, root, key, path, 0, 0); ++ if (ret < 0) ++ return ret; ++ + if (ret == 0) { + char *src_copy; + char *dst_copy; +@@ -365,6 +369,30 @@ static noinline int overwrite_item(struct btrfs_trans_handle *trans, + return 0; + } + ++ /* ++ * We need to load the old nbytes into the inode so when we ++ * replay the extents we've logged we get the right nbytes. ++ */ ++ if (inode_item) { ++ struct btrfs_inode_item *item; ++ u64 nbytes; ++ ++ item = btrfs_item_ptr(path->nodes[0], path->slots[0], ++ struct btrfs_inode_item); ++ nbytes = btrfs_inode_nbytes(path->nodes[0], item); ++ item = btrfs_item_ptr(eb, slot, ++ struct btrfs_inode_item); ++ btrfs_set_inode_nbytes(eb, item, nbytes); ++ } ++ } else if (inode_item) { ++ struct btrfs_inode_item *item; ++ ++ /* ++ * New inode, set nbytes to 0 so that the nbytes comes out ++ * properly when we replay the extents. ++ */ ++ item = btrfs_item_ptr(eb, slot, struct btrfs_inode_item); ++ btrfs_set_inode_nbytes(eb, item, 0); + } + insert: + btrfs_release_path(path); +@@ -486,7 +514,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, + u64 extent_end; + u64 alloc_hint; + u64 start = key->offset; +- u64 saved_nbytes; ++ u64 nbytes = 0; + struct btrfs_file_extent_item *item; + struct inode *inode = NULL; + unsigned long size; +@@ -496,10 +524,19 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, + found_type = btrfs_file_extent_type(eb, item); + + if (found_type == BTRFS_FILE_EXTENT_REG || +- found_type == BTRFS_FILE_EXTENT_PREALLOC) +- extent_end = start + btrfs_file_extent_num_bytes(eb, item); +- else if (found_type == BTRFS_FILE_EXTENT_INLINE) { ++ found_type == BTRFS_FILE_EXTENT_PREALLOC) { ++ nbytes = btrfs_file_extent_num_bytes(eb, item); ++ extent_end = start + nbytes; ++ ++ /* ++ * We don't add to the inodes nbytes if we are prealloc or a ++ * hole. ++ */ ++ if (btrfs_file_extent_disk_bytenr(eb, item) == 0) ++ nbytes = 0; ++ } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { + size = btrfs_file_extent_inline_len(eb, item); ++ nbytes = btrfs_file_extent_ram_bytes(eb, item); + extent_end = (start + size + mask) & ~mask; + } else { + ret = 0; +@@ -548,7 +585,6 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, + } + btrfs_release_path(path); + +- saved_nbytes = inode_get_bytes(inode); + /* drop any overlapping extents */ + ret = btrfs_drop_extents(trans, inode, start, extent_end, + &alloc_hint, 1); +@@ -636,7 +672,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, + BUG_ON(ret); + } + +- inode_set_bytes(inode, saved_nbytes); ++ inode_add_bytes(inode, nbytes); + btrfs_update_inode(trans, root, inode); + out: + if (inode) +diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c +index 5849e3e..32b12e5 100644 +--- a/fs/hfsplus/extents.c ++++ b/fs/hfsplus/extents.c +@@ -517,7 +517,7 @@ void hfsplus_file_truncate(struct inode *inode) + struct address_space *mapping = inode->i_mapping; + struct page *page; + void *fsdata; +- u32 size = inode->i_size; ++ loff_t size = inode->i_size; + + res = pagecache_write_begin(NULL, mapping, size, 0, + AOP_FLAG_UNINTERRUPTIBLE, +diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h +index 72cbf08..c6fb815 100644 +--- a/include/linux/kvm_host.h ++++ b/include/linux/kvm_host.h +@@ -427,7 +427,7 @@ int kvm_write_guest(struct kvm *kvm, gpa_t gpa, const void *data, + int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, + void *data, unsigned long len); + int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc, +- gpa_t gpa); ++ gpa_t gpa, unsigned long len); + int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len); + int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len); + struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn); +diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h +index fa7cc72..b0bcce0 100644 +--- a/include/linux/kvm_types.h ++++ b/include/linux/kvm_types.h +@@ -71,6 +71,7 @@ struct gfn_to_hva_cache { + u64 generation; + gpa_t gpa; + unsigned long hva; ++ unsigned long len; + struct kvm_memory_slot *memslot; + }; + +diff --git a/include/linux/mm.h b/include/linux/mm.h +index 441a564..ece5ff4 100644 +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -1507,6 +1507,8 @@ int vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr, + unsigned long pfn); + int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, + unsigned long pfn); ++int vm_iomap_memory(struct vm_area_struct *vma, phys_addr_t start, unsigned long len); ++ + + struct page *follow_page(struct vm_area_struct *, unsigned long address, + unsigned int foll_flags); +diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h +index 1a6b004..29ce7e4 100644 +--- a/include/linux/ssb/ssb_driver_chipcommon.h ++++ b/include/linux/ssb/ssb_driver_chipcommon.h +@@ -219,6 +219,7 @@ + #define SSB_CHIPCO_PMU_CTL 0x0600 /* PMU control */ + #define SSB_CHIPCO_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */ + #define SSB_CHIPCO_PMU_CTL_ILP_DIV_SHIFT 16 ++#define SSB_CHIPCO_PMU_CTL_PLL_UPD 0x00000400 + #define SSB_CHIPCO_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */ + #define SSB_CHIPCO_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */ + #define SSB_CHIPCO_PMU_CTL_ALPREQEN 0x00000080 /* ALP req enable */ +@@ -661,5 +662,6 @@ enum ssb_pmu_ldo_volt_id { + void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc, + enum ssb_pmu_ldo_volt_id id, u32 voltage); + void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on); ++void ssb_pmu_spuravoid_pllupdate(struct ssb_chipcommon *cc, int spuravoid); + + #endif /* LINUX_SSB_CHIPCO_H_ */ +--- a/kernel/hrtimer.c ++++ b/kernel/hrtimer.c +@@ -61,6 +61,7 @@ + DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) = + { + ++ .lock = __RAW_SPIN_LOCK_UNLOCKED(hrtimer_bases.lock), + .clock_base = + { + { +@@ -1640,8 +1641,6 @@ static void __cpuinit init_hrtimers_cpu(int cpu) + struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu); + int i; + +- raw_spin_lock_init(&cpu_base->lock); +- + for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) { + cpu_base->clock_base[i].cpu_base = cpu_base; + timerqueue_init_head(&cpu_base->clock_base[i].active); +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index e1718bc..4b6c546 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -1653,8 +1653,10 @@ static void try_to_wake_up_local(struct task_struct *p) + { + struct rq *rq = task_rq(p); + +- BUG_ON(rq != this_rq()); +- BUG_ON(p == current); ++ if (WARN_ON_ONCE(rq != this_rq()) || ++ WARN_ON_ONCE(p == current)) ++ return; ++ + lockdep_assert_held(&rq->lock); + + if (!raw_spin_trylock(&p->pi_lock)) { +diff --git a/kernel/signal.c b/kernel/signal.c +index 32b10d4..959df4f 100644 +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -2867,7 +2867,7 @@ do_send_specific(pid_t tgid, pid_t pid, int sig, struct siginfo *info) + + static int do_tkill(pid_t tgid, pid_t pid, int sig) + { +- struct siginfo info; ++ struct siginfo info = {}; + + info.si_signo = sig; + info.si_errno = 0; +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index e427969..69b21bb 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -2906,7 +2906,17 @@ int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, + break; + } + +- if (absent || ++ /* ++ * We need call hugetlb_fault for both hugepages under migration ++ * (in which case hugetlb_fault waits for the migration,) and ++ * hwpoisoned hugepages (in which case we need to prevent the ++ * caller from accessing to them.) In order to do this, we use ++ * here is_swap_pte instead of is_hugetlb_entry_migration and ++ * is_hugetlb_entry_hwpoisoned. This is because it simply covers ++ * both cases, and because we can't follow correct pages ++ * directly from any kind of swap entries. ++ */ ++ if (absent || is_swap_pte(huge_ptep_get(pte)) || + ((flags & FOLL_WRITE) && !pte_write(huge_ptep_get(pte)))) { + int ret; + +diff --git a/mm/memory.c b/mm/memory.c +index 2f42aab..17d8661 100644 +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -2329,6 +2329,53 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, + } + EXPORT_SYMBOL(remap_pfn_range); + ++/** ++ * vm_iomap_memory - remap memory to userspace ++ * @vma: user vma to map to ++ * @start: start of area ++ * @len: size of area ++ * ++ * This is a simplified io_remap_pfn_range() for common driver use. The ++ * driver just needs to give us the physical memory range to be mapped, ++ * we'll figure out the rest from the vma information. ++ * ++ * NOTE! Some drivers might want to tweak vma->vm_page_prot first to get ++ * whatever write-combining details or similar. ++ */ ++int vm_iomap_memory(struct vm_area_struct *vma, phys_addr_t start, unsigned long len) ++{ ++ unsigned long vm_len, pfn, pages; ++ ++ /* Check that the physical memory area passed in looks valid */ ++ if (start + len < start) ++ return -EINVAL; ++ /* ++ * You *really* shouldn't map things that aren't page-aligned, ++ * but we've historically allowed it because IO memory might ++ * just have smaller alignment. ++ */ ++ len += start & ~PAGE_MASK; ++ pfn = start >> PAGE_SHIFT; ++ pages = (len + ~PAGE_MASK) >> PAGE_SHIFT; ++ if (pfn + pages < pfn) ++ return -EINVAL; ++ ++ /* We start the mapping 'vm_pgoff' pages into the area */ ++ if (vma->vm_pgoff > pages) ++ return -EINVAL; ++ pfn += vma->vm_pgoff; ++ pages -= vma->vm_pgoff; ++ ++ /* Can we fit all of the mapping? */ ++ vm_len = vma->vm_end - vma->vm_start; ++ if (vm_len >> PAGE_SHIFT > pages) ++ return -EINVAL; ++ ++ /* Ok, let it rip */ ++ return io_remap_pfn_range(vma, vma->vm_start, pfn, vm_len, vma->vm_page_prot); ++} ++EXPORT_SYMBOL(vm_iomap_memory); ++ + static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd, + unsigned long addr, unsigned long end, + pte_fn_t fn, void *data) +diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c +index d535b34..d776291 100644 +--- a/sound/core/pcm_native.c ++++ b/sound/core/pcm_native.c +@@ -3209,18 +3209,10 @@ EXPORT_SYMBOL_GPL(snd_pcm_lib_default_mmap); + int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, + struct vm_area_struct *area) + { +- long size; +- unsigned long offset; ++ struct snd_pcm_runtime *runtime = substream->runtime;; + + area->vm_page_prot = pgprot_noncached(area->vm_page_prot); +- area->vm_flags |= VM_IO; +- size = area->vm_end - area->vm_start; +- offset = area->vm_pgoff << PAGE_SHIFT; +- if (io_remap_pfn_range(area, area->vm_start, +- (substream->runtime->dma_addr + offset) >> PAGE_SHIFT, +- size, area->vm_page_prot)) +- return -EAGAIN; +- return 0; ++ return vm_iomap_memory(area, runtime->dma_addr, runtime->dma_bytes); + } + + EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem); +diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c +index dcaf272c26..9f477f6 100644 +--- a/virt/kvm/ioapic.c ++++ b/virt/kvm/ioapic.c +@@ -73,9 +73,12 @@ static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic, + u32 redir_index = (ioapic->ioregsel - 0x10) >> 1; + u64 redir_content; + +- ASSERT(redir_index < IOAPIC_NUM_PINS); ++ if (redir_index < IOAPIC_NUM_PINS) ++ redir_content = ++ ioapic->redirtbl[redir_index].bits; ++ else ++ redir_content = ~0ULL; + +- redir_content = ioapic->redirtbl[redir_index].bits; + result = (ioapic->ioregsel & 0x1) ? + (redir_content >> 32) & 0xffffffff : + redir_content & 0xffffffff; +diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c +index 71b9036..bdfbc1b 100644 +--- a/virt/kvm/kvm_main.c ++++ b/virt/kvm/kvm_main.c +@@ -1382,21 +1382,38 @@ int kvm_write_guest(struct kvm *kvm, gpa_t gpa, const void *data, + } + + int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc, +- gpa_t gpa) ++ gpa_t gpa, unsigned long len) + { + struct kvm_memslots *slots = kvm_memslots(kvm); + int offset = offset_in_page(gpa); +- gfn_t gfn = gpa >> PAGE_SHIFT; ++ gfn_t start_gfn = gpa >> PAGE_SHIFT; ++ gfn_t end_gfn = (gpa + len - 1) >> PAGE_SHIFT; ++ gfn_t nr_pages_needed = end_gfn - start_gfn + 1; ++ gfn_t nr_pages_avail; + + ghc->gpa = gpa; + ghc->generation = slots->generation; +- ghc->memslot = gfn_to_memslot(kvm, gfn); +- ghc->hva = gfn_to_hva_many(ghc->memslot, gfn, NULL); +- if (!kvm_is_error_hva(ghc->hva)) ++ ghc->len = len; ++ ghc->memslot = gfn_to_memslot(kvm, start_gfn); ++ ghc->hva = gfn_to_hva_many(ghc->memslot, start_gfn, &nr_pages_avail); ++ if (!kvm_is_error_hva(ghc->hva) && nr_pages_avail >= nr_pages_needed) { + ghc->hva += offset; +- else +- return -EFAULT; +- ++ } else { ++ /* ++ * If the requested region crosses two memslots, we still ++ * verify that the entire region is valid here. ++ */ ++ while (start_gfn <= end_gfn) { ++ ghc->memslot = gfn_to_memslot(kvm, start_gfn); ++ ghc->hva = gfn_to_hva_many(ghc->memslot, start_gfn, ++ &nr_pages_avail); ++ if (kvm_is_error_hva(ghc->hva)) ++ return -EFAULT; ++ start_gfn += nr_pages_avail; ++ } ++ /* Use the slow path for cross page reads and writes. */ ++ ghc->memslot = NULL; ++ } + return 0; + } + EXPORT_SYMBOL_GPL(kvm_gfn_to_hva_cache_init); +@@ -1407,8 +1424,13 @@ int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, + struct kvm_memslots *slots = kvm_memslots(kvm); + int r; + ++ BUG_ON(len > ghc->len); ++ + if (slots->generation != ghc->generation) +- kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa); ++ kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa, ghc->len); ++ ++ if (unlikely(!ghc->memslot)) ++ return kvm_write_guest(kvm, ghc->gpa, data, len); + + if (kvm_is_error_hva(ghc->hva)) + return -EFAULT; +@@ -1428,8 +1450,13 @@ int kvm_read_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, + struct kvm_memslots *slots = kvm_memslots(kvm); + int r; + ++ BUG_ON(len > ghc->len); ++ + if (slots->generation != ghc->generation) +- kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa); ++ kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa, ghc->len); ++ ++ if (unlikely(!ghc->memslot)) ++ return kvm_read_guest(kvm, ghc->gpa, data, len); + + if (kvm_is_error_hva(ghc->hva)) + return -EFAULT; diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.42-43.patch b/patch/kernel/sun8i-default/0001-patch-3.4.42-43.patch new file mode 100644 index 000000000..9e288d6fb --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.42-43.patch @@ -0,0 +1,1345 @@ +diff --git a/Makefile b/Makefile +index 35c00db..af0a40e 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 42 ++SUBLEVEL = 43 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h +index 76e4a52..656de8b 100644 +--- a/arch/sparc/include/asm/pgtable_64.h ++++ b/arch/sparc/include/asm/pgtable_64.h +@@ -780,6 +780,7 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma, + return remap_pfn_range(vma, from, phys_base >> PAGE_SHIFT, size, prot); + } + ++#include + #include + + /* We provide our own get_unmapped_area to cope with VA holes and +diff --git a/arch/sparc/include/asm/switch_to_64.h b/arch/sparc/include/asm/switch_to_64.h +index 7923c4a..9c2a92d 100644 +--- a/arch/sparc/include/asm/switch_to_64.h ++++ b/arch/sparc/include/asm/switch_to_64.h +@@ -18,8 +18,7 @@ do { \ + * and 2 stores in this critical code path. -DaveM + */ + #define switch_to(prev, next, last) \ +-do { flush_tlb_pending(); \ +- save_and_clear_fpu(); \ ++do { save_and_clear_fpu(); \ + /* If you are tempted to conditionalize the following */ \ + /* so that ASI is only written if it changes, think again. */ \ + __asm__ __volatile__("wr %%g0, %0, %%asi" \ +diff --git a/arch/sparc/include/asm/tlbflush_64.h b/arch/sparc/include/asm/tlbflush_64.h +index 2ef4634..f0d6a97 100644 +--- a/arch/sparc/include/asm/tlbflush_64.h ++++ b/arch/sparc/include/asm/tlbflush_64.h +@@ -11,24 +11,40 @@ + struct tlb_batch { + struct mm_struct *mm; + unsigned long tlb_nr; ++ unsigned long active; + unsigned long vaddrs[TLB_BATCH_NR]; + }; + + extern void flush_tsb_kernel_range(unsigned long start, unsigned long end); + extern void flush_tsb_user(struct tlb_batch *tb); ++extern void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr); + + /* TLB flush operations. */ + +-extern void flush_tlb_pending(void); ++static inline void flush_tlb_mm(struct mm_struct *mm) ++{ ++} ++ ++static inline void flush_tlb_page(struct vm_area_struct *vma, ++ unsigned long vmaddr) ++{ ++} ++ ++static inline void flush_tlb_range(struct vm_area_struct *vma, ++ unsigned long start, unsigned long end) ++{ ++} ++ ++#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE + +-#define flush_tlb_range(vma,start,end) \ +- do { (void)(start); flush_tlb_pending(); } while (0) +-#define flush_tlb_page(vma,addr) flush_tlb_pending() +-#define flush_tlb_mm(mm) flush_tlb_pending() ++extern void flush_tlb_pending(void); ++extern void arch_enter_lazy_mmu_mode(void); ++extern void arch_leave_lazy_mmu_mode(void); ++#define arch_flush_lazy_mmu_mode() do {} while (0) + + /* Local cpu only. */ + extern void __flush_tlb_all(void); +- ++extern void __flush_tlb_page(unsigned long context, unsigned long vaddr); + extern void __flush_tlb_kernel_range(unsigned long start, unsigned long end); + + #ifndef CONFIG_SMP +@@ -38,15 +54,24 @@ do { flush_tsb_kernel_range(start,end); \ + __flush_tlb_kernel_range(start,end); \ + } while (0) + ++static inline void global_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr) ++{ ++ __flush_tlb_page(CTX_HWBITS(mm->context), vaddr); ++} ++ + #else /* CONFIG_SMP */ + + extern void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end); ++extern void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr); + + #define flush_tlb_kernel_range(start, end) \ + do { flush_tsb_kernel_range(start,end); \ + smp_flush_tlb_kernel_range(start, end); \ + } while (0) + ++#define global_flush_tlb_page(mm, vaddr) \ ++ smp_flush_tlb_page(mm, vaddr) ++ + #endif /* ! CONFIG_SMP */ + + #endif /* _SPARC64_TLBFLUSH_H */ +diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c +index 3b1bd7c..bb2886a 100644 +--- a/arch/sparc/kernel/smp_64.c ++++ b/arch/sparc/kernel/smp_64.c +@@ -856,7 +856,7 @@ void smp_tsb_sync(struct mm_struct *mm) + } + + extern unsigned long xcall_flush_tlb_mm; +-extern unsigned long xcall_flush_tlb_pending; ++extern unsigned long xcall_flush_tlb_page; + extern unsigned long xcall_flush_tlb_kernel_range; + extern unsigned long xcall_fetch_glob_regs; + extern unsigned long xcall_receive_signal; +@@ -1070,23 +1070,56 @@ local_flush_and_out: + put_cpu(); + } + ++struct tlb_pending_info { ++ unsigned long ctx; ++ unsigned long nr; ++ unsigned long *vaddrs; ++}; ++ ++static void tlb_pending_func(void *info) ++{ ++ struct tlb_pending_info *t = info; ++ ++ __flush_tlb_pending(t->ctx, t->nr, t->vaddrs); ++} ++ + void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long *vaddrs) + { + u32 ctx = CTX_HWBITS(mm->context); ++ struct tlb_pending_info info; + int cpu = get_cpu(); + ++ info.ctx = ctx; ++ info.nr = nr; ++ info.vaddrs = vaddrs; ++ + if (mm == current->mm && atomic_read(&mm->mm_users) == 1) + cpumask_copy(mm_cpumask(mm), cpumask_of(cpu)); + else +- smp_cross_call_masked(&xcall_flush_tlb_pending, +- ctx, nr, (unsigned long) vaddrs, +- mm_cpumask(mm)); ++ smp_call_function_many(mm_cpumask(mm), tlb_pending_func, ++ &info, 1); + + __flush_tlb_pending(ctx, nr, vaddrs); + + put_cpu(); + } + ++void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr) ++{ ++ unsigned long context = CTX_HWBITS(mm->context); ++ int cpu = get_cpu(); ++ ++ if (mm == current->mm && atomic_read(&mm->mm_users) == 1) ++ cpumask_copy(mm_cpumask(mm), cpumask_of(cpu)); ++ else ++ smp_cross_call_masked(&xcall_flush_tlb_page, ++ context, vaddr, 0, ++ mm_cpumask(mm)); ++ __flush_tlb_page(context, vaddr); ++ ++ put_cpu(); ++} ++ + void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end) + { + start &= PAGE_MASK; +diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c +index b1f279c..afd021e 100644 +--- a/arch/sparc/mm/tlb.c ++++ b/arch/sparc/mm/tlb.c +@@ -24,11 +24,17 @@ static DEFINE_PER_CPU(struct tlb_batch, tlb_batch); + void flush_tlb_pending(void) + { + struct tlb_batch *tb = &get_cpu_var(tlb_batch); ++ struct mm_struct *mm = tb->mm; + +- if (tb->tlb_nr) { +- flush_tsb_user(tb); ++ if (!tb->tlb_nr) ++ goto out; + +- if (CTX_VALID(tb->mm->context)) { ++ flush_tsb_user(tb); ++ ++ if (CTX_VALID(mm->context)) { ++ if (tb->tlb_nr == 1) { ++ global_flush_tlb_page(mm, tb->vaddrs[0]); ++ } else { + #ifdef CONFIG_SMP + smp_flush_tlb_pending(tb->mm, tb->tlb_nr, + &tb->vaddrs[0]); +@@ -37,12 +43,30 @@ void flush_tlb_pending(void) + tb->tlb_nr, &tb->vaddrs[0]); + #endif + } +- tb->tlb_nr = 0; + } + ++ tb->tlb_nr = 0; ++ ++out: + put_cpu_var(tlb_batch); + } + ++void arch_enter_lazy_mmu_mode(void) ++{ ++ struct tlb_batch *tb = &__get_cpu_var(tlb_batch); ++ ++ tb->active = 1; ++} ++ ++void arch_leave_lazy_mmu_mode(void) ++{ ++ struct tlb_batch *tb = &__get_cpu_var(tlb_batch); ++ ++ if (tb->tlb_nr) ++ flush_tlb_pending(); ++ tb->active = 0; ++} ++ + void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr, + pte_t *ptep, pte_t orig, int fullmm) + { +@@ -90,6 +114,12 @@ no_cache_flush: + nr = 0; + } + ++ if (!tb->active) { ++ global_flush_tlb_page(mm, vaddr); ++ flush_tsb_user_page(mm, vaddr); ++ goto out; ++ } ++ + if (nr == 0) + tb->mm = mm; + +@@ -98,5 +128,6 @@ no_cache_flush: + if (nr >= TLB_BATCH_NR) + flush_tlb_pending(); + ++out: + put_cpu_var(tlb_batch); + } +diff --git a/arch/sparc/mm/tsb.c b/arch/sparc/mm/tsb.c +index c52add7..f4e84f3 100644 +--- a/arch/sparc/mm/tsb.c ++++ b/arch/sparc/mm/tsb.c +@@ -7,11 +7,10 @@ + #include + #include + #include +-#include +-#include +-#include + #include ++#include + #include ++#include + #include + + extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES]; +@@ -46,23 +45,27 @@ void flush_tsb_kernel_range(unsigned long start, unsigned long end) + } + } + +-static void __flush_tsb_one(struct tlb_batch *tb, unsigned long hash_shift, +- unsigned long tsb, unsigned long nentries) ++static void __flush_tsb_one_entry(unsigned long tsb, unsigned long v, ++ unsigned long hash_shift, ++ unsigned long nentries) + { +- unsigned long i; ++ unsigned long tag, ent, hash; + +- for (i = 0; i < tb->tlb_nr; i++) { +- unsigned long v = tb->vaddrs[i]; +- unsigned long tag, ent, hash; ++ v &= ~0x1UL; ++ hash = tsb_hash(v, hash_shift, nentries); ++ ent = tsb + (hash * sizeof(struct tsb)); ++ tag = (v >> 22UL); + +- v &= ~0x1UL; ++ tsb_flush(ent, tag); ++} + +- hash = tsb_hash(v, hash_shift, nentries); +- ent = tsb + (hash * sizeof(struct tsb)); +- tag = (v >> 22UL); ++static void __flush_tsb_one(struct tlb_batch *tb, unsigned long hash_shift, ++ unsigned long tsb, unsigned long nentries) ++{ ++ unsigned long i; + +- tsb_flush(ent, tag); +- } ++ for (i = 0; i < tb->tlb_nr; i++) ++ __flush_tsb_one_entry(tsb, tb->vaddrs[i], hash_shift, nentries); + } + + void flush_tsb_user(struct tlb_batch *tb) +@@ -90,6 +93,30 @@ void flush_tsb_user(struct tlb_batch *tb) + spin_unlock_irqrestore(&mm->context.lock, flags); + } + ++void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr) ++{ ++ unsigned long nentries, base, flags; ++ ++ spin_lock_irqsave(&mm->context.lock, flags); ++ ++ base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb; ++ nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries; ++ if (tlb_type == cheetah_plus || tlb_type == hypervisor) ++ base = __pa(base); ++ __flush_tsb_one_entry(base, vaddr, PAGE_SHIFT, nentries); ++ ++#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) ++ if (mm->context.tsb_block[MM_TSB_HUGE].tsb) { ++ base = (unsigned long) mm->context.tsb_block[MM_TSB_HUGE].tsb; ++ nentries = mm->context.tsb_block[MM_TSB_HUGE].tsb_nentries; ++ if (tlb_type == cheetah_plus || tlb_type == hypervisor) ++ base = __pa(base); ++ __flush_tsb_one_entry(base, vaddr, HPAGE_SHIFT, nentries); ++ } ++#endif ++ spin_unlock_irqrestore(&mm->context.lock, flags); ++} ++ + #if defined(CONFIG_SPARC64_PAGE_SIZE_8KB) + #define HV_PGSZ_IDX_BASE HV_PGSZ_IDX_8K + #define HV_PGSZ_MASK_BASE HV_PGSZ_MASK_8K +diff --git a/arch/sparc/mm/ultra.S b/arch/sparc/mm/ultra.S +index 874162a..dd10caa 100644 +--- a/arch/sparc/mm/ultra.S ++++ b/arch/sparc/mm/ultra.S +@@ -53,6 +53,33 @@ __flush_tlb_mm: /* 18 insns */ + nop + + .align 32 ++ .globl __flush_tlb_page ++__flush_tlb_page: /* 22 insns */ ++ /* %o0 = context, %o1 = vaddr */ ++ rdpr %pstate, %g7 ++ andn %g7, PSTATE_IE, %g2 ++ wrpr %g2, %pstate ++ mov SECONDARY_CONTEXT, %o4 ++ ldxa [%o4] ASI_DMMU, %g2 ++ stxa %o0, [%o4] ASI_DMMU ++ andcc %o1, 1, %g0 ++ andn %o1, 1, %o3 ++ be,pn %icc, 1f ++ or %o3, 0x10, %o3 ++ stxa %g0, [%o3] ASI_IMMU_DEMAP ++1: stxa %g0, [%o3] ASI_DMMU_DEMAP ++ membar #Sync ++ stxa %g2, [%o4] ASI_DMMU ++ sethi %hi(KERNBASE), %o4 ++ flush %o4 ++ retl ++ wrpr %g7, 0x0, %pstate ++ nop ++ nop ++ nop ++ nop ++ ++ .align 32 + .globl __flush_tlb_pending + __flush_tlb_pending: /* 26 insns */ + /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ +@@ -203,6 +230,31 @@ __cheetah_flush_tlb_mm: /* 19 insns */ + retl + wrpr %g7, 0x0, %pstate + ++__cheetah_flush_tlb_page: /* 22 insns */ ++ /* %o0 = context, %o1 = vaddr */ ++ rdpr %pstate, %g7 ++ andn %g7, PSTATE_IE, %g2 ++ wrpr %g2, 0x0, %pstate ++ wrpr %g0, 1, %tl ++ mov PRIMARY_CONTEXT, %o4 ++ ldxa [%o4] ASI_DMMU, %g2 ++ srlx %g2, CTX_PGSZ1_NUC_SHIFT, %o3 ++ sllx %o3, CTX_PGSZ1_NUC_SHIFT, %o3 ++ or %o0, %o3, %o0 /* Preserve nucleus page size fields */ ++ stxa %o0, [%o4] ASI_DMMU ++ andcc %o1, 1, %g0 ++ be,pn %icc, 1f ++ andn %o1, 1, %o3 ++ stxa %g0, [%o3] ASI_IMMU_DEMAP ++1: stxa %g0, [%o3] ASI_DMMU_DEMAP ++ membar #Sync ++ stxa %g2, [%o4] ASI_DMMU ++ sethi %hi(KERNBASE), %o4 ++ flush %o4 ++ wrpr %g0, 0, %tl ++ retl ++ wrpr %g7, 0x0, %pstate ++ + __cheetah_flush_tlb_pending: /* 27 insns */ + /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ + rdpr %pstate, %g7 +@@ -269,6 +321,20 @@ __hypervisor_flush_tlb_mm: /* 10 insns */ + retl + nop + ++__hypervisor_flush_tlb_page: /* 11 insns */ ++ /* %o0 = context, %o1 = vaddr */ ++ mov %o0, %g2 ++ mov %o1, %o0 /* ARG0: vaddr + IMMU-bit */ ++ mov %g2, %o1 /* ARG1: mmu context */ ++ mov HV_MMU_ALL, %o2 /* ARG2: flags */ ++ srlx %o0, PAGE_SHIFT, %o0 ++ sllx %o0, PAGE_SHIFT, %o0 ++ ta HV_MMU_UNMAP_ADDR_TRAP ++ brnz,pn %o0, __hypervisor_tlb_tl0_error ++ mov HV_MMU_UNMAP_ADDR_TRAP, %o1 ++ retl ++ nop ++ + __hypervisor_flush_tlb_pending: /* 16 insns */ + /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ + sllx %o1, 3, %g1 +@@ -339,6 +405,13 @@ cheetah_patch_cachetlbops: + call tlb_patch_one + mov 19, %o2 + ++ sethi %hi(__flush_tlb_page), %o0 ++ or %o0, %lo(__flush_tlb_page), %o0 ++ sethi %hi(__cheetah_flush_tlb_page), %o1 ++ or %o1, %lo(__cheetah_flush_tlb_page), %o1 ++ call tlb_patch_one ++ mov 22, %o2 ++ + sethi %hi(__flush_tlb_pending), %o0 + or %o0, %lo(__flush_tlb_pending), %o0 + sethi %hi(__cheetah_flush_tlb_pending), %o1 +@@ -397,10 +470,9 @@ xcall_flush_tlb_mm: /* 21 insns */ + nop + nop + +- .globl xcall_flush_tlb_pending +-xcall_flush_tlb_pending: /* 21 insns */ +- /* %g5=context, %g1=nr, %g7=vaddrs[] */ +- sllx %g1, 3, %g1 ++ .globl xcall_flush_tlb_page ++xcall_flush_tlb_page: /* 17 insns */ ++ /* %g5=context, %g1=vaddr */ + mov PRIMARY_CONTEXT, %g4 + ldxa [%g4] ASI_DMMU, %g2 + srlx %g2, CTX_PGSZ1_NUC_SHIFT, %g4 +@@ -408,20 +480,16 @@ xcall_flush_tlb_pending: /* 21 insns */ + or %g5, %g4, %g5 + mov PRIMARY_CONTEXT, %g4 + stxa %g5, [%g4] ASI_DMMU +-1: sub %g1, (1 << 3), %g1 +- ldx [%g7 + %g1], %g5 +- andcc %g5, 0x1, %g0 ++ andcc %g1, 0x1, %g0 + be,pn %icc, 2f +- +- andn %g5, 0x1, %g5 ++ andn %g1, 0x1, %g5 + stxa %g0, [%g5] ASI_IMMU_DEMAP + 2: stxa %g0, [%g5] ASI_DMMU_DEMAP + membar #Sync +- brnz,pt %g1, 1b +- nop + stxa %g2, [%g4] ASI_DMMU + retry + nop ++ nop + + .globl xcall_flush_tlb_kernel_range + xcall_flush_tlb_kernel_range: /* 25 insns */ +@@ -596,15 +664,13 @@ __hypervisor_xcall_flush_tlb_mm: /* 21 insns */ + membar #Sync + retry + +- .globl __hypervisor_xcall_flush_tlb_pending +-__hypervisor_xcall_flush_tlb_pending: /* 21 insns */ +- /* %g5=ctx, %g1=nr, %g7=vaddrs[], %g2,%g3,%g4,g6=scratch */ +- sllx %g1, 3, %g1 ++ .globl __hypervisor_xcall_flush_tlb_page ++__hypervisor_xcall_flush_tlb_page: /* 17 insns */ ++ /* %g5=ctx, %g1=vaddr */ + mov %o0, %g2 + mov %o1, %g3 + mov %o2, %g4 +-1: sub %g1, (1 << 3), %g1 +- ldx [%g7 + %g1], %o0 /* ARG0: virtual address */ ++ mov %g1, %o0 /* ARG0: virtual address */ + mov %g5, %o1 /* ARG1: mmu context */ + mov HV_MMU_ALL, %o2 /* ARG2: flags */ + srlx %o0, PAGE_SHIFT, %o0 +@@ -613,8 +679,6 @@ __hypervisor_xcall_flush_tlb_pending: /* 21 insns */ + mov HV_MMU_UNMAP_ADDR_TRAP, %g6 + brnz,a,pn %o0, __hypervisor_tlb_xcall_error + mov %o0, %g5 +- brnz,pt %g1, 1b +- nop + mov %g2, %o0 + mov %g3, %o1 + mov %g4, %o2 +@@ -697,6 +761,13 @@ hypervisor_patch_cachetlbops: + call tlb_patch_one + mov 10, %o2 + ++ sethi %hi(__flush_tlb_page), %o0 ++ or %o0, %lo(__flush_tlb_page), %o0 ++ sethi %hi(__hypervisor_flush_tlb_page), %o1 ++ or %o1, %lo(__hypervisor_flush_tlb_page), %o1 ++ call tlb_patch_one ++ mov 11, %o2 ++ + sethi %hi(__flush_tlb_pending), %o0 + or %o0, %lo(__flush_tlb_pending), %o0 + sethi %hi(__hypervisor_flush_tlb_pending), %o1 +@@ -728,12 +799,12 @@ hypervisor_patch_cachetlbops: + call tlb_patch_one + mov 21, %o2 + +- sethi %hi(xcall_flush_tlb_pending), %o0 +- or %o0, %lo(xcall_flush_tlb_pending), %o0 +- sethi %hi(__hypervisor_xcall_flush_tlb_pending), %o1 +- or %o1, %lo(__hypervisor_xcall_flush_tlb_pending), %o1 ++ sethi %hi(xcall_flush_tlb_page), %o0 ++ or %o0, %lo(xcall_flush_tlb_page), %o0 ++ sethi %hi(__hypervisor_xcall_flush_tlb_page), %o1 ++ or %o1, %lo(__hypervisor_xcall_flush_tlb_page), %o1 + call tlb_patch_one +- mov 21, %o2 ++ mov 17, %o2 + + sethi %hi(xcall_flush_tlb_kernel_range), %o0 + or %o0, %lo(xcall_flush_tlb_kernel_range), %o0 +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index d9f646f..d9f8358 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1888,6 +1888,7 @@ err_detach: + write_unlock_bh(&bond->lock); + + err_close: ++ slave_dev->priv_flags &= ~IFF_BONDING; + dev_close(slave_dev); + + err_unset_master: +@@ -4864,9 +4865,18 @@ static int __net_init bond_net_init(struct net *net) + static void __net_exit bond_net_exit(struct net *net) + { + struct bond_net *bn = net_generic(net, bond_net_id); ++ struct bonding *bond, *tmp_bond; ++ LIST_HEAD(list); + + bond_destroy_sysfs(bn); + bond_destroy_proc_dir(bn); ++ ++ /* Kill off any bonds created after unregistering bond rtnl ops */ ++ rtnl_lock(); ++ list_for_each_entry_safe(bond, tmp_bond, &bn->dev_list, bond_list) ++ unregister_netdevice_queue(bond->dev, &list); ++ unregister_netdevice_many(&list); ++ rtnl_unlock(); + } + + static struct pernet_operations bond_net_ops = { +diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e.h b/drivers/net/ethernet/atheros/atl1e/atl1e.h +index edfdf6b..b5fd934 100644 +--- a/drivers/net/ethernet/atheros/atl1e/atl1e.h ++++ b/drivers/net/ethernet/atheros/atl1e/atl1e.h +@@ -186,7 +186,7 @@ struct atl1e_tpd_desc { + /* how about 0x2000 */ + #define MAX_TX_BUF_LEN 0x2000 + #define MAX_TX_BUF_SHIFT 13 +-/*#define MAX_TX_BUF_LEN 0x3000 */ ++#define MAX_TSO_SEG_SIZE 0x3c00 + + /* rrs word 1 bit 0:31 */ + #define RRS_RX_CSUM_MASK 0xFFFF +diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +index f964151..d53509e 100644 +--- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c ++++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +@@ -2354,6 +2354,7 @@ static int __devinit atl1e_probe(struct pci_dev *pdev, + + INIT_WORK(&adapter->reset_task, atl1e_reset_task); + INIT_WORK(&adapter->link_chg_task, atl1e_link_chg_task); ++ netif_set_gso_max_size(netdev, MAX_TSO_SEG_SIZE); + err = register_netdev(netdev); + if (err) { + netdev_err(netdev, "register netdevice failed\n"); +diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c +index d939bd7..bf9f987 100644 +--- a/drivers/tty/tty_io.c ++++ b/drivers/tty/tty_io.c +@@ -938,6 +938,14 @@ void start_tty(struct tty_struct *tty) + + EXPORT_SYMBOL(start_tty); + ++static void tty_update_time(struct timespec *time) ++{ ++ unsigned long sec = get_seconds(); ++ sec -= sec % 60; ++ if ((long)(sec - time->tv_sec) > 0) ++ time->tv_sec = sec; ++} ++ + /** + * tty_read - read method for tty device files + * @file: pointer to tty file +@@ -974,8 +982,10 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, + else + i = -EIO; + tty_ldisc_deref(ld); ++ + if (i > 0) +- inode->i_atime = current_fs_time(inode->i_sb); ++ tty_update_time(&inode->i_atime); ++ + return i; + } + +@@ -1078,7 +1088,7 @@ static inline ssize_t do_tty_write( + } + if (written) { + struct inode *inode = file->f_path.dentry->d_inode; +- inode->i_mtime = current_fs_time(inode->i_sb); ++ tty_update_time(&inode->i_mtime); + ret = written; + } + out: +diff --git a/fs/aio.c b/fs/aio.c +index e7f2fad..cdc8dc4 100644 +--- a/fs/aio.c ++++ b/fs/aio.c +@@ -1094,9 +1094,9 @@ static int aio_read_evt(struct kioctx *ioctx, struct io_event *ent) + spin_unlock(&info->ring_lock); + + out: +- kunmap_atomic(ring); + dprintk("leaving aio_read_evt: %d h%lu t%lu\n", ret, + (unsigned long)ring->head, (unsigned long)ring->tail); ++ kunmap_atomic(ring); + return ret; + } + +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index e517695..dc6c687 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -232,9 +232,9 @@ struct netdev_hw_addr { + #define NETDEV_HW_ADDR_T_SLAVE 3 + #define NETDEV_HW_ADDR_T_UNICAST 4 + #define NETDEV_HW_ADDR_T_MULTICAST 5 +- bool synced; + bool global_use; + int refcount; ++ int synced; + struct rcu_head rcu_head; + }; + +diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h +index 4aea870..dc4d49a 100644 +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -2392,6 +2392,13 @@ static inline void nf_reset(struct sk_buff *skb) + #endif + } + ++static inline void nf_reset_trace(struct sk_buff *skb) ++{ ++#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) ++ skb->nf_trace = 0; ++#endif ++} ++ + /* Note: This doesn't put any conntrack and bridge info in dst. */ + static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src) + { +diff --git a/include/linux/socket.h b/include/linux/socket.h +index b84bbd4..8f15b1d 100644 +--- a/include/linux/socket.h ++++ b/include/linux/socket.h +@@ -316,7 +316,8 @@ struct ucred { + /* IPX options */ + #define IPX_TYPE 1 + +-extern void cred_to_ucred(struct pid *pid, const struct cred *cred, struct ucred *ucred); ++extern void cred_to_ucred(struct pid *pid, const struct cred *cred, struct ucred *ucred, ++ bool use_effective); + + extern int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len); + extern int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov, +diff --git a/include/net/scm.h b/include/net/scm.h +index 0c0017c..9f211cf 100644 +--- a/include/net/scm.h ++++ b/include/net/scm.h +@@ -50,7 +50,7 @@ static __inline__ void scm_set_cred(struct scm_cookie *scm, + { + scm->pid = get_pid(pid); + scm->cred = cred ? get_cred(cred) : NULL; +- cred_to_ucred(pid, cred, &scm->creds); ++ cred_to_ucred(pid, cred, &scm->creds, false); + } + + static __inline__ void scm_destroy_cred(struct scm_cookie *scm) +diff --git a/net/atm/common.c b/net/atm/common.c +index 0c0ad93..f0a9b7e 100644 +--- a/net/atm/common.c ++++ b/net/atm/common.c +@@ -520,6 +520,8 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, + struct sk_buff *skb; + int copied, error = -EINVAL; + ++ msg->msg_namelen = 0; ++ + if (sock->state != SS_CONNECTED) + return -ENOTCONN; + +diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c +index 9d9a6a3..68b3992 100644 +--- a/net/ax25/af_ax25.c ++++ b/net/ax25/af_ax25.c +@@ -1646,6 +1646,7 @@ static int ax25_recvmsg(struct kiocb *iocb, struct socket *sock, + ax25_address src; + const unsigned char *mac = skb_mac_header(skb); + ++ memset(sax, 0, sizeof(struct full_sockaddr_ax25)); + ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL, + &digi, NULL, NULL); + sax->sax25_family = AF_AX25; +diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c +index 6fb68a9..c294348 100644 +--- a/net/bluetooth/af_bluetooth.c ++++ b/net/bluetooth/af_bluetooth.c +@@ -240,6 +240,8 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, + if (flags & (MSG_OOB)) + return -EOPNOTSUPP; + ++ msg->msg_namelen = 0; ++ + skb = skb_recv_datagram(sk, flags, noblock, &err); + if (!skb) { + if (sk->sk_shutdown & RCV_SHUTDOWN) +@@ -247,8 +249,6 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, + return err; + } + +- msg->msg_namelen = 0; +- + copied = skb->len; + if (len < copied) { + msg->msg_flags |= MSG_TRUNC; +diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c +index 8d1edd7..c79db7f 100644 +--- a/net/bluetooth/rfcomm/sock.c ++++ b/net/bluetooth/rfcomm/sock.c +@@ -628,6 +628,7 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock, + + if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) { + rfcomm_dlc_accept(d); ++ msg->msg_namelen = 0; + return 0; + } + +diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c +index 5016fa5..24a6886 100644 +--- a/net/caif/caif_socket.c ++++ b/net/caif/caif_socket.c +@@ -287,6 +287,8 @@ static int caif_seqpkt_recvmsg(struct kiocb *iocb, struct socket *sock, + if (m->msg_flags&MSG_OOB) + goto read_error; + ++ m->msg_namelen = 0; ++ + skb = skb_recv_datagram(sk, flags, 0 , &ret); + if (!skb) + goto read_error; +diff --git a/net/core/dev.c b/net/core/dev.c +index 9e2e29b..dd12421 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -1628,6 +1628,7 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) + skb->mark = 0; + secpath_reset(skb); + nf_reset(skb); ++ nf_reset_trace(skb); + return netif_rx(skb); + } + EXPORT_SYMBOL_GPL(dev_forward_skb); +@@ -1894,6 +1895,9 @@ static void skb_warn_bad_offload(const struct sk_buff *skb) + struct net_device *dev = skb->dev; + const char *driver = ""; + ++ if (!net_ratelimit()) ++ return; ++ + if (dev && dev->dev.parent) + driver = dev_driver_string(dev->dev.parent); + +diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c +index 76f6d0b..0346e59 100644 +--- a/net/core/dev_addr_lists.c ++++ b/net/core/dev_addr_lists.c +@@ -57,7 +57,7 @@ static int __hw_addr_add_ex(struct netdev_hw_addr_list *list, + ha->type = addr_type; + ha->refcount = 1; + ha->global_use = global; +- ha->synced = false; ++ ha->synced = 0; + list_add_tail_rcu(&ha->list, &list->list); + list->count++; + return 0; +@@ -155,7 +155,7 @@ int __hw_addr_sync(struct netdev_hw_addr_list *to_list, + addr_len, ha->type); + if (err) + break; +- ha->synced = true; ++ ha->synced++; + ha->refcount++; + } else if (ha->refcount == 1) { + __hw_addr_del(to_list, ha->addr, addr_len, ha->type); +@@ -176,7 +176,7 @@ void __hw_addr_unsync(struct netdev_hw_addr_list *to_list, + if (ha->synced) { + __hw_addr_del(to_list, ha->addr, + addr_len, ha->type); +- ha->synced = false; ++ ha->synced--; + __hw_addr_del(from_list, ha->addr, + addr_len, ha->type); + } +diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c +index 3db960c..a133427 100644 +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -1066,7 +1066,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) + rcu_read_lock(); + cb->seq = net->dev_base_seq; + +- if (nlmsg_parse(cb->nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX, ++ if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX, + ifla_policy) >= 0) { + + if (tb[IFLA_EXT_MASK]) +@@ -1910,7 +1910,7 @@ static u16 rtnl_calcit(struct sk_buff *skb, struct nlmsghdr *nlh) + u32 ext_filter_mask = 0; + u16 min_ifinfo_dump_size = 0; + +- if (nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX, ++ if (nlmsg_parse(nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX, + ifla_policy) >= 0) { + if (tb[IFLA_EXT_MASK]) + ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); +diff --git a/net/core/sock.c b/net/core/sock.c +index 4b469e3..f8b5030 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -815,15 +815,20 @@ EXPORT_SYMBOL(sock_setsockopt); + + + void cred_to_ucred(struct pid *pid, const struct cred *cred, +- struct ucred *ucred) ++ struct ucred *ucred, bool use_effective) + { + ucred->pid = pid_vnr(pid); + ucred->uid = ucred->gid = -1; + if (cred) { + struct user_namespace *current_ns = current_user_ns(); + +- ucred->uid = user_ns_map_uid(current_ns, cred, cred->euid); +- ucred->gid = user_ns_map_gid(current_ns, cred, cred->egid); ++ if (use_effective) { ++ ucred->uid = user_ns_map_uid(current_ns, cred, cred->euid); ++ ucred->gid = user_ns_map_gid(current_ns, cred, cred->egid); ++ } else { ++ ucred->uid = user_ns_map_uid(current_ns, cred, cred->uid); ++ ucred->gid = user_ns_map_gid(current_ns, cred, cred->gid); ++ } + } + } + EXPORT_SYMBOL_GPL(cred_to_ucred); +@@ -984,7 +989,8 @@ int sock_getsockopt(struct socket *sock, int level, int optname, + struct ucred peercred; + if (len > sizeof(peercred)) + len = sizeof(peercred); +- cred_to_ucred(sk->sk_peer_pid, sk->sk_peer_cred, &peercred); ++ cred_to_ucred(sk->sk_peer_pid, sk->sk_peer_cred, ++ &peercred, true); + if (copy_to_user(optval, &peercred, len)) + return -EFAULT; + goto lenout; +diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c +index cb982a6..e814e2a 100644 +--- a/net/ipv4/esp4.c ++++ b/net/ipv4/esp4.c +@@ -139,8 +139,6 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) + + /* skb is pure payload to encrypt */ + +- err = -ENOMEM; +- + esp = x->data; + aead = esp->aead; + alen = crypto_aead_authsize(aead); +@@ -176,8 +174,10 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) + } + + tmp = esp_alloc_tmp(aead, nfrags + sglists, seqhilen); +- if (!tmp) ++ if (!tmp) { ++ err = -ENOMEM; + goto error; ++ } + + seqhi = esp_tmp_seqhi(tmp); + iv = esp_tmp_iv(aead, tmp, seqhilen); +diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c +index 8e28871..4a40457 100644 +--- a/net/ipv4/ip_fragment.c ++++ b/net/ipv4/ip_fragment.c +@@ -251,8 +251,7 @@ static void ip_expire(unsigned long arg) + if (!head->dev) + goto out_rcu_unlock; + +- /* skb dst is stale, drop it, and perform route lookup again */ +- skb_dst_drop(head); ++ /* skb has no dst, perform route lookup again */ + iph = ip_hdr(head); + err = ip_route_input_noref(head, iph->daddr, iph->saddr, + iph->tos, head->dev); +@@ -517,8 +516,16 @@ found: + qp->q.last_in |= INET_FRAG_FIRST_IN; + + if (qp->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && +- qp->q.meat == qp->q.len) +- return ip_frag_reasm(qp, prev, dev); ++ qp->q.meat == qp->q.len) { ++ unsigned long orefdst = skb->_skb_refdst; ++ ++ skb->_skb_refdst = 0UL; ++ err = ip_frag_reasm(qp, prev, dev); ++ skb->_skb_refdst = orefdst; ++ return err; ++ } ++ ++ skb_dst_drop(skb); + + write_lock(&ip4_frags.lock); + list_move_tail(&qp->q.lru_list, &qp->q.net->lru_list); +diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c +index eab2a7f..550aa2a 100644 +--- a/net/ipv4/syncookies.c ++++ b/net/ipv4/syncookies.c +@@ -347,8 +347,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, + * hasn't changed since we received the original syn, but I see + * no easy way to do this. + */ +- flowi4_init_output(&fl4, 0, sk->sk_mark, RT_CONN_FLAGS(sk), +- RT_SCOPE_UNIVERSE, IPPROTO_TCP, ++ flowi4_init_output(&fl4, sk->sk_bound_dev_if, sk->sk_mark, ++ RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, IPPROTO_TCP, + inet_sk_flowi_flags(sk), + (opt && opt->srr) ? opt->faddr : ireq->rmt_addr, + ireq->loc_addr, th->source, th->dest); +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index 0a1f159..762c78f 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -116,6 +116,7 @@ int sysctl_tcp_abc __read_mostly; + #define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */ + #define FLAG_NONHEAD_RETRANS_ACKED 0x1000 /* Non-head rexmitted data was ACKed */ + #define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */ ++#define FLAG_UPDATE_TS_RECENT 0x4000 /* tcp_replace_ts_recent() */ + + #define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) + #define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) +@@ -3707,6 +3708,27 @@ static void tcp_send_challenge_ack(struct sock *sk) + } + } + ++static void tcp_store_ts_recent(struct tcp_sock *tp) ++{ ++ tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval; ++ tp->rx_opt.ts_recent_stamp = get_seconds(); ++} ++ ++static void tcp_replace_ts_recent(struct tcp_sock *tp, u32 seq) ++{ ++ if (tp->rx_opt.saw_tstamp && !after(seq, tp->rcv_wup)) { ++ /* PAWS bug workaround wrt. ACK frames, the PAWS discard ++ * extra check below makes sure this can only happen ++ * for pure ACK frames. -DaveM ++ * ++ * Not only, also it occurs for expired timestamps. ++ */ ++ ++ if (tcp_paws_check(&tp->rx_opt, 0)) ++ tcp_store_ts_recent(tp); ++ } ++} ++ + /* This routine deals with incoming acks, but not outgoing ones. */ + static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) + { +@@ -3756,6 +3778,12 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) + prior_fackets = tp->fackets_out; + prior_in_flight = tcp_packets_in_flight(tp); + ++ /* ts_recent update must be made after we are sure that the packet ++ * is in window. ++ */ ++ if (flag & FLAG_UPDATE_TS_RECENT) ++ tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); ++ + if (!(flag & FLAG_SLOWPATH) && after(ack, prior_snd_una)) { + /* Window is constant, pure forward advance. + * No more checks are required. +@@ -4053,27 +4081,6 @@ const u8 *tcp_parse_md5sig_option(const struct tcphdr *th) + EXPORT_SYMBOL(tcp_parse_md5sig_option); + #endif + +-static inline void tcp_store_ts_recent(struct tcp_sock *tp) +-{ +- tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval; +- tp->rx_opt.ts_recent_stamp = get_seconds(); +-} +- +-static inline void tcp_replace_ts_recent(struct tcp_sock *tp, u32 seq) +-{ +- if (tp->rx_opt.saw_tstamp && !after(seq, tp->rcv_wup)) { +- /* PAWS bug workaround wrt. ACK frames, the PAWS discard +- * extra check below makes sure this can only happen +- * for pure ACK frames. -DaveM +- * +- * Not only, also it occurs for expired timestamps. +- */ +- +- if (tcp_paws_check(&tp->rx_opt, 0)) +- tcp_store_ts_recent(tp); +- } +-} +- + /* Sorry, PAWS as specified is broken wrt. pure-ACKs -DaveM + * + * It is not fatal. If this ACK does _not_ change critical state (seqs, window) +@@ -5577,14 +5584,10 @@ slow_path: + return 0; + + step5: +- if (th->ack && tcp_ack(sk, skb, FLAG_SLOWPATH) < 0) ++ if (th->ack && ++ tcp_ack(sk, skb, FLAG_SLOWPATH | FLAG_UPDATE_TS_RECENT) < 0) + goto discard; + +- /* ts_recent update must be made after we are sure that the packet +- * is in window. +- */ +- tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); +- + tcp_rcv_rtt_measure_ts(sk, skb); + + /* Process urgent data. */ +@@ -5948,7 +5951,8 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, + + /* step 5: check the ACK field */ + if (th->ack) { +- int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH) > 0; ++ int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH | ++ FLAG_UPDATE_TS_RECENT) > 0; + + switch (sk->sk_state) { + case TCP_SYN_RECV: +@@ -6055,11 +6059,6 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, + } else + goto discard; + +- /* ts_recent update must be made after we are sure that the packet +- * is in window. +- */ +- tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); +- + /* step 6: check the URG bit */ + tcp_urg(sk, skb, th); + +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c +index 4dca494..9db21e3 100644 +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -2154,8 +2154,12 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) + */ + TCP_SKB_CB(skb)->when = tcp_time_stamp; + +- /* make sure skb->data is aligned on arches that require it */ +- if (unlikely(NET_IP_ALIGN && ((unsigned long)skb->data & 3))) { ++ /* make sure skb->data is aligned on arches that require it ++ * and check if ack-trimming & collapsing extended the headroom ++ * beyond what csum_start can cover. ++ */ ++ if (unlikely((NET_IP_ALIGN && ((unsigned long)skb->data & 3)) || ++ skb_headroom(skb) >= 0xFFFF)) { + struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER, + GFP_ATOMIC); + err = nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index 541a719..2c496d6 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -2399,6 +2399,9 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) + static void init_loopback(struct net_device *dev) + { + struct inet6_dev *idev; ++ struct net_device *sp_dev; ++ struct inet6_ifaddr *sp_ifa; ++ struct rt6_info *sp_rt; + + /* ::1 */ + +@@ -2410,6 +2413,30 @@ static void init_loopback(struct net_device *dev) + } + + add_addr(idev, &in6addr_loopback, 128, IFA_HOST); ++ ++ /* Add routes to other interface's IPv6 addresses */ ++ for_each_netdev(dev_net(dev), sp_dev) { ++ if (!strcmp(sp_dev->name, dev->name)) ++ continue; ++ ++ idev = __in6_dev_get(sp_dev); ++ if (!idev) ++ continue; ++ ++ read_lock_bh(&idev->lock); ++ list_for_each_entry(sp_ifa, &idev->addr_list, if_list) { ++ ++ if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE)) ++ continue; ++ ++ sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); ++ ++ /* Failure cases are ignored */ ++ if (!IS_ERR(sp_rt)) ++ ip6_ins_rt(sp_rt); ++ } ++ read_unlock_bh(&idev->lock); ++ } + } + + static void addrconf_add_linklocal(struct inet6_dev *idev, const struct in6_addr *addr) +diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c +index 5ff412f..6bda7aa 100644 +--- a/net/ipv6/reassembly.c ++++ b/net/ipv6/reassembly.c +@@ -385,8 +385,17 @@ found: + } + + if (fq->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && +- fq->q.meat == fq->q.len) +- return ip6_frag_reasm(fq, prev, dev); ++ fq->q.meat == fq->q.len) { ++ int res; ++ unsigned long orefdst = skb->_skb_refdst; ++ ++ skb->_skb_refdst = 0UL; ++ res = ip6_frag_reasm(fq, prev, dev); ++ skb->_skb_refdst = orefdst; ++ return res; ++ } ++ ++ skb_dst_drop(skb); + + write_lock(&ip6_frags.lock); + list_move_tail(&fq->q.lru_list, &fq->q.net->lru_list); +diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c +index d6c291c..bd25678 100644 +--- a/net/irda/af_irda.c ++++ b/net/irda/af_irda.c +@@ -1386,6 +1386,8 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock, + + IRDA_DEBUG(4, "%s()\n", __func__); + ++ msg->msg_namelen = 0; ++ + skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, + flags & MSG_DONTWAIT, &err); + if (!skb) +diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c +index cd6f7a9..625bc50 100644 +--- a/net/iucv/af_iucv.c ++++ b/net/iucv/af_iucv.c +@@ -1331,6 +1331,8 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, + struct sk_buff *skb, *rskb, *cskb; + int err = 0; + ++ msg->msg_namelen = 0; ++ + if ((sk->sk_state == IUCV_DISCONN) && + skb_queue_empty(&iucv->backlog_skb_q) && + skb_queue_empty(&sk->sk_receive_queue) && +diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c +index df08d77..e4d2fbb 100644 +--- a/net/llc/af_llc.c ++++ b/net/llc/af_llc.c +@@ -721,6 +721,8 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, + int target; /* Read at least this many bytes */ + long timeo; + ++ msg->msg_namelen = 0; ++ + lock_sock(sk); + copied = -ENOTCONN; + if (unlikely(sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN)) +diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c +index 1b9024e..7ed9b1d 100644 +--- a/net/netrom/af_netrom.c ++++ b/net/netrom/af_netrom.c +@@ -1177,6 +1177,7 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock, + } + + if (sax != NULL) { ++ memset(sax, 0, sizeof(*sax)); + sax->sax25_family = AF_NETROM; + skb_copy_from_linear_data_offset(skb, 7, sax->sax25_call.ax25_call, + AX25_ADDR_LEN); +diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c +index c13e02e..0c2115f 100644 +--- a/net/nfc/llcp/sock.c ++++ b/net/nfc/llcp/sock.c +@@ -514,6 +514,8 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock, + + pr_debug("%p %zu\n", sk, len); + ++ msg->msg_namelen = 0; ++ + lock_sock(sk); + + if (sk->sk_state == LLCP_CLOSED && +diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c +index c4719ce..7f645d1 100644 +--- a/net/rose/af_rose.c ++++ b/net/rose/af_rose.c +@@ -1257,6 +1257,7 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock, + skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); + + if (srose != NULL) { ++ memset(srose, 0, msg->msg_namelen); + srose->srose_family = AF_ROSE; + srose->srose_addr = rose->dest_addr; + srose->srose_call = rose->dest_call; +diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c +index 599f67a..b7cddb9 100644 +--- a/net/sched/sch_cbq.c ++++ b/net/sched/sch_cbq.c +@@ -963,8 +963,11 @@ cbq_dequeue(struct Qdisc *sch) + cbq_update(q); + if ((incr -= incr2) < 0) + incr = 0; ++ q->now += incr; ++ } else { ++ if (now > q->now) ++ q->now = now; + } +- q->now += incr; + q->now_rt = now; + + for (;;) { +diff --git a/net/sctp/auth.c b/net/sctp/auth.c +index bf81204..333926d 100644 +--- a/net/sctp/auth.c ++++ b/net/sctp/auth.c +@@ -71,7 +71,7 @@ void sctp_auth_key_put(struct sctp_auth_bytes *key) + return; + + if (atomic_dec_and_test(&key->refcnt)) { +- kfree(key); ++ kzfree(key); + SCTP_DBG_OBJCNT_DEC(keys); + } + } +diff --git a/net/tipc/socket.c b/net/tipc/socket.c +index 29e957f..1441ab7 100644 +--- a/net/tipc/socket.c ++++ b/net/tipc/socket.c +@@ -829,6 +829,7 @@ static void set_orig_addr(struct msghdr *m, struct tipc_msg *msg) + if (addr) { + addr->family = AF_TIPC; + addr->addrtype = TIPC_ADDR_ID; ++ memset(&addr->addr, 0, sizeof(addr->addr)); + addr->addr.id.ref = msg_origport(msg); + addr->addr.id.node = msg_orignode(msg); + addr->addr.name.domain = 0; /* could leave uninitialized */ +@@ -948,6 +949,9 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock, + goto exit; + } + ++ /* will be updated in set_orig_addr() if needed */ ++ m->msg_namelen = 0; ++ + timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); + restart: + +@@ -1074,6 +1078,9 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock, + goto exit; + } + ++ /* will be updated in set_orig_addr() if needed */ ++ m->msg_namelen = 0; ++ + target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); + timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); + restart: +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index fa5289a..c4821fd 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -1986,7 +1986,7 @@ again: + if ((UNIXCB(skb).pid != siocb->scm->pid) || + (UNIXCB(skb).cred != siocb->scm->cred)) + break; +- } else { ++ } else if (test_bit(SOCK_PASSCRED, &sock->flags)) { + /* Copy credentials */ + scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred); + check_creds = 1; diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.43-44.patch b/patch/kernel/sun8i-default/0001-patch-3.4.43-44.patch new file mode 100644 index 000000000..f23d764c5 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.43-44.patch @@ -0,0 +1,1716 @@ +diff --git a/Makefile b/Makefile +index af0a40e..c156161 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 43 ++SUBLEVEL = 44 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/arm/configs/at91sam9g45_defconfig b/arch/arm/configs/at91sam9g45_defconfig +index 606d48f..8aab786 100644 +--- a/arch/arm/configs/at91sam9g45_defconfig ++++ b/arch/arm/configs/at91sam9g45_defconfig +@@ -173,7 +173,6 @@ CONFIG_MMC=y + # CONFIG_MMC_BLOCK_BOUNCE is not set + CONFIG_SDIO_UART=m + CONFIG_MMC_ATMELMCI=y +-CONFIG_MMC_ATMELMCI_DMA=y + CONFIG_LEDS_ATMEL_PWM=y + CONFIG_LEDS_GPIO=y + CONFIG_LEDS_TRIGGER_TIMER=y +diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h +index 41dc31f..cc5e50f 100644 +--- a/arch/arm/include/asm/pgtable.h ++++ b/arch/arm/include/asm/pgtable.h +@@ -61,6 +61,15 @@ extern void __pgd_error(const char *file, int line, pgd_t); + #define FIRST_USER_ADDRESS PAGE_SIZE + + /* ++ * Use TASK_SIZE as the ceiling argument for free_pgtables() and ++ * free_pgd_range() to avoid freeing the modules pmd when LPAE is enabled (pmd ++ * page shared between user and kernel). ++ */ ++#ifdef CONFIG_ARM_LPAE ++#define USER_PGTABLES_CEILING TASK_SIZE ++#endif ++ ++/* + * The pgprot_* and protection_map entries will be fixed up in runtime + * to include the cachable and bufferable bits based on memory policy, + * as well as any architecture dependent bits like global/ASID and SMP +diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c +index 55293a7..5db5174 100644 +--- a/arch/arm/mach-at91/setup.c ++++ b/arch/arm/mach-at91/setup.c +@@ -326,7 +326,7 @@ static void at91_dt_rstc(void) + + of_id = of_match_node(rstc_ids, np); + if (!of_id) +- panic("AT91: rtsc no restart function availlable\n"); ++ panic("AT91: rtsc no restart function available\n"); + + arm_pm_restart = of_id->data; + +diff --git a/arch/avr32/configs/favr-32_defconfig b/arch/avr32/configs/favr-32_defconfig +index 19973b0..59e4cc9 100644 +--- a/arch/avr32/configs/favr-32_defconfig ++++ b/arch/avr32/configs/favr-32_defconfig +@@ -122,7 +122,6 @@ CONFIG_USB_G_SERIAL=m + CONFIG_USB_CDC_COMPOSITE=m + CONFIG_MMC=y + CONFIG_MMC_ATMELMCI=y +-CONFIG_MMC_ATMELMCI_DMA=y + CONFIG_NEW_LEDS=y + CONFIG_LEDS_CLASS=y + CONFIG_LEDS_ATMEL_PWM=m +diff --git a/arch/avr32/configs/merisc_defconfig b/arch/avr32/configs/merisc_defconfig +index 3befab9..65de443 100644 +--- a/arch/avr32/configs/merisc_defconfig ++++ b/arch/avr32/configs/merisc_defconfig +@@ -102,7 +102,6 @@ CONFIG_FRAMEBUFFER_CONSOLE=y + CONFIG_LOGO=y + CONFIG_MMC=y + CONFIG_MMC_ATMELMCI=y +-CONFIG_MMC_ATMELMCI_DMA=y + CONFIG_NEW_LEDS=y + CONFIG_LEDS_CLASS=y + CONFIG_LEDS_ATMEL_PWM=y +diff --git a/arch/ia64/include/asm/futex.h b/arch/ia64/include/asm/futex.h +index d2bf1fd..76acbcd 100644 +--- a/arch/ia64/include/asm/futex.h ++++ b/arch/ia64/include/asm/futex.h +@@ -106,16 +106,15 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, + return -EFAULT; + + { +- register unsigned long r8 __asm ("r8"); ++ register unsigned long r8 __asm ("r8") = 0; + unsigned long prev; + __asm__ __volatile__( + " mf;; \n" +- " mov %0=r0 \n" + " mov ar.ccv=%4;; \n" + "[1:] cmpxchg4.acq %1=[%2],%3,ar.ccv \n" + " .xdata4 \"__ex_table\", 1b-., 2f-. \n" + "[2:]" +- : "=r" (r8), "=r" (prev) ++ : "+r" (r8), "=&r" (prev) + : "r" (uaddr), "r" (newval), + "rO" ((long) (unsigned) oldval) + : "memory"); +diff --git a/arch/ia64/include/asm/mca.h b/arch/ia64/include/asm/mca.h +index 43f96ab..8c70961 100644 +--- a/arch/ia64/include/asm/mca.h ++++ b/arch/ia64/include/asm/mca.h +@@ -143,6 +143,7 @@ extern unsigned long __per_cpu_mca[NR_CPUS]; + extern int cpe_vector; + extern int ia64_cpe_irq; + extern void ia64_mca_init(void); ++extern void ia64_mca_irq_init(void); + extern void ia64_mca_cpu_init(void *); + extern void ia64_os_mca_dispatch(void); + extern void ia64_os_mca_dispatch_end(void); +diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c +index ad69606..f2c41828 100644 +--- a/arch/ia64/kernel/irq.c ++++ b/arch/ia64/kernel/irq.c +@@ -23,6 +23,8 @@ + #include + #include + ++#include ++ + /* + * 'what should we do if we get a hw irq event on an illegal vector'. + * each architecture has to answer this themselves. +@@ -83,6 +85,12 @@ bool is_affinity_mask_valid(const struct cpumask *cpumask) + + #endif /* CONFIG_SMP */ + ++int __init arch_early_irq_init(void) ++{ ++ ia64_mca_irq_init(); ++ return 0; ++} ++ + #ifdef CONFIG_HOTPLUG_CPU + unsigned int vectors_in_migration[NR_IRQS]; + +diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c +index 65bf9cd..d7396db 100644 +--- a/arch/ia64/kernel/mca.c ++++ b/arch/ia64/kernel/mca.c +@@ -2074,22 +2074,16 @@ ia64_mca_init(void) + printk(KERN_INFO "MCA related initialization done\n"); + } + ++ + /* +- * ia64_mca_late_init +- * +- * Opportunity to setup things that require initialization later +- * than ia64_mca_init. Setup a timer to poll for CPEs if the +- * platform doesn't support an interrupt driven mechanism. +- * +- * Inputs : None +- * Outputs : Status ++ * These pieces cannot be done in ia64_mca_init() because it is called before ++ * early_irq_init() which would wipe out our percpu irq registrations. But we ++ * cannot leave them until ia64_mca_late_init() because by then all the other ++ * processors have been brought online and have set their own CMC vectors to ++ * point at a non-existant action. Called from arch_early_irq_init(). + */ +-static int __init +-ia64_mca_late_init(void) ++void __init ia64_mca_irq_init(void) + { +- if (!mca_init) +- return 0; +- + /* + * Configure the CMCI/P vector and handler. Interrupts for CMC are + * per-processor, so AP CMC interrupts are setup in smp_callin() (smpboot.c). +@@ -2108,6 +2102,23 @@ ia64_mca_late_init(void) + /* Setup the CPEI/P handler */ + register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction); + #endif ++} ++ ++/* ++ * ia64_mca_late_init ++ * ++ * Opportunity to setup things that require initialization later ++ * than ia64_mca_init. Setup a timer to poll for CPEs if the ++ * platform doesn't support an interrupt driven mechanism. ++ * ++ * Inputs : None ++ * Outputs : Status ++ */ ++static int __init ++ia64_mca_late_init(void) ++{ ++ if (!mca_init) ++ return 0; + + register_hotcpu_notifier(&mca_cpu_notifier); + +diff --git a/arch/ia64/kvm/vtlb.c b/arch/ia64/kvm/vtlb.c +index 4332f7e..a7869f8 100644 +--- a/arch/ia64/kvm/vtlb.c ++++ b/arch/ia64/kvm/vtlb.c +@@ -256,7 +256,7 @@ u64 guest_vhpt_lookup(u64 iha, u64 *pte) + "srlz.d;;" + "ssm psr.i;;" + "srlz.d;;" +- : "=r"(ret) : "r"(iha), "r"(pte):"memory"); ++ : "=&r"(ret) : "r"(iha), "r"(pte) : "memory"); + + return ret; + } +diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S +index 9e07bd0..1a3607b 100644 +--- a/arch/powerpc/kernel/head_64.S ++++ b/arch/powerpc/kernel/head_64.S +@@ -489,6 +489,7 @@ _GLOBAL(copy_and_flush) + sync + addi r5,r5,8 + addi r6,r6,8 ++ isync + blr + + .align 8 +diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c +index 1d75c92..ad697f8 100644 +--- a/arch/powerpc/platforms/cell/spufs/inode.c ++++ b/arch/powerpc/platforms/cell/spufs/inode.c +@@ -99,6 +99,7 @@ spufs_new_inode(struct super_block *sb, umode_t mode) + if (!inode) + goto out; + ++ inode->i_ino = get_next_ino(); + inode->i_mode = mode; + inode->i_uid = current_fsuid(); + inode->i_gid = current_fsgid(); +diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c +index 3dafc60..a14a835 100644 +--- a/arch/x86/kernel/irq.c ++++ b/arch/x86/kernel/irq.c +@@ -165,10 +165,6 @@ u64 arch_irq_stat_cpu(unsigned int cpu) + u64 arch_irq_stat(void) + { + u64 sum = atomic_read(&irq_err_count); +- +-#ifdef CONFIG_X86_IO_APIC +- sum += atomic_read(&irq_mis_count); +-#endif + return sum; + } + +diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c +index 8375622..8c45818 100644 +--- a/arch/x86/kvm/emulate.c ++++ b/arch/x86/kvm/emulate.c +@@ -3737,6 +3737,10 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op, + break; + case OpMem8: + ctxt->memop.bytes = 1; ++ if (ctxt->memop.type == OP_REG) { ++ ctxt->memop.addr.reg = decode_register(ctxt, ctxt->modrm_rm, 1); ++ fetch_register_operand(&ctxt->memop); ++ } + goto mem_common; + case OpMem16: + ctxt->memop.bytes = 2; +diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c +index 194dbcd..2992678 100644 +--- a/arch/x86/xen/enlighten.c ++++ b/arch/x86/xen/enlighten.c +@@ -1515,8 +1515,11 @@ static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self, + switch (action) { + case CPU_UP_PREPARE: + xen_vcpu_setup(cpu); +- if (xen_have_vector_callback) ++ if (xen_have_vector_callback) { + xen_init_lock_cpu(cpu); ++ if (xen_feature(XENFEAT_hvm_safe_pvclock)) ++ xen_setup_timer(cpu); ++ } + break; + default: + break; +diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c +index 0296a95..054cc01 100644 +--- a/arch/x86/xen/time.c ++++ b/arch/x86/xen/time.c +@@ -497,7 +497,11 @@ static void xen_hvm_setup_cpu_clockevents(void) + { + int cpu = smp_processor_id(); + xen_setup_runstate_info(cpu); +- xen_setup_timer(cpu); ++ /* ++ * xen_setup_timer(cpu) - snprintf is bad in atomic context. Hence ++ * doing it xen_hvm_cpu_notify (which gets called by smp_init during ++ * early bootup and also during CPU hotplug events). ++ */ + xen_setup_cpu_clockevents(); + } + +diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c +index 7aff631..5b0f075 100644 +--- a/drivers/acpi/pci_root.c ++++ b/drivers/acpi/pci_root.c +@@ -247,8 +247,8 @@ static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, + *control &= OSC_PCI_CONTROL_MASKS; + capbuf[OSC_CONTROL_TYPE] = *control | root->osc_control_set; + } else { +- /* Run _OSC query for all possible controls. */ +- capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS; ++ /* Run _OSC query only with existing controls. */ ++ capbuf[OSC_CONTROL_TYPE] = root->osc_control_set; + } + + status = acpi_pci_run_osc(root->device->handle, capbuf, &result); +diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c +index 2bded76..d70106e 100644 +--- a/drivers/i2c/busses/i2c-xiic.c ++++ b/drivers/i2c/busses/i2c-xiic.c +@@ -311,10 +311,8 @@ static void xiic_fill_tx_fifo(struct xiic_i2c *i2c) + /* last message in transfer -> STOP */ + data |= XIIC_TX_DYN_STOP_MASK; + dev_dbg(i2c->adap.dev.parent, "%s TX STOP\n", __func__); +- +- xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data); +- } else +- xiic_setreg8(i2c, XIIC_DTR_REG_OFFSET, data); ++ } ++ xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data); + } + } + +diff --git a/drivers/md/md.c b/drivers/md/md.c +index e0930bb..7b45b5e 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -1587,8 +1587,8 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_ + sector, count, 1) == 0) + return -EINVAL; + } +- } else if (sb->bblog_offset == 0) +- rdev->badblocks.shift = -1; ++ } else if (sb->bblog_offset != 0) ++ rdev->badblocks.shift = 0; + + if (!refdev) { + ret = 1; +@@ -3107,7 +3107,7 @@ int md_rdev_init(struct md_rdev *rdev) + * be used - I wonder if that matters + */ + rdev->badblocks.count = 0; +- rdev->badblocks.shift = 0; ++ rdev->badblocks.shift = -1; /* disabled until explicitly enabled */ + rdev->badblocks.page = kmalloc(PAGE_SIZE, GFP_KERNEL); + seqlock_init(&rdev->badblocks.lock); + if (rdev->badblocks.page == NULL) +@@ -3179,9 +3179,6 @@ static struct md_rdev *md_import_device(dev_t newdev, int super_format, int supe + goto abort_free; + } + } +- if (super_format == -1) +- /* hot-add for 0.90, or non-persistent: so no badblocks */ +- rdev->badblocks.shift = -1; + + return rdev; + +diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c +index 8d816cc..105f820 100644 +--- a/drivers/mfd/adp5520.c ++++ b/drivers/mfd/adp5520.c +@@ -36,6 +36,7 @@ struct adp5520_chip { + struct blocking_notifier_head notifier_list; + int irq; + unsigned long id; ++ uint8_t mode; + }; + + static int __adp5520_read(struct i2c_client *client, +@@ -326,7 +327,10 @@ static int adp5520_suspend(struct device *dev) + struct i2c_client *client = to_i2c_client(dev); + struct adp5520_chip *chip = dev_get_drvdata(&client->dev); + +- adp5520_clr_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY); ++ adp5520_read(chip->dev, ADP5520_MODE_STATUS, &chip->mode); ++ /* All other bits are W1C */ ++ chip->mode &= ADP5520_BL_EN | ADP5520_DIM_EN | ADP5520_nSTNBY; ++ adp5520_write(chip->dev, ADP5520_MODE_STATUS, 0); + return 0; + } + +@@ -335,7 +339,7 @@ static int adp5520_resume(struct device *dev) + struct i2c_client *client = to_i2c_client(dev); + struct adp5520_chip *chip = dev_get_drvdata(&client->dev); + +- adp5520_set_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY); ++ adp5520_write(chip->dev, ADP5520_MODE_STATUS, chip->mode); + return 0; + } + #endif +diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c +index 54df5ad..5352cd7 100644 +--- a/drivers/mmc/core/mmc.c ++++ b/drivers/mmc/core/mmc.c +@@ -385,13 +385,13 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) + ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]; + card->ext_csd.raw_trim_mult = + ext_csd[EXT_CSD_TRIM_MULT]; ++ card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT]; + if (card->ext_csd.rev >= 4) { + /* + * Enhanced area feature support -- check whether the eMMC + * card has the Enhanced area enabled. If so, export enhanced + * area offset and size to user by adding sysfs interface. + */ +- card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT]; + if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) && + (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) { + hc_erase_grp_sz = +diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig +index 2bc06e7..dbdd907 100644 +--- a/drivers/mmc/host/Kconfig ++++ b/drivers/mmc/host/Kconfig +@@ -297,16 +297,6 @@ config MMC_ATMELMCI + + endchoice + +-config MMC_ATMELMCI_DMA +- bool "Atmel MCI DMA support" +- depends on MMC_ATMELMCI && (AVR32 || ARCH_AT91SAM9G45) && DMA_ENGINE +- help +- Say Y here to have the Atmel MCI driver use a DMA engine to +- do data transfers and thus increase the throughput and +- reduce the CPU utilization. +- +- If unsure, say N. +- + config MMC_IMX + tristate "Motorola i.MX Multimedia Card Interface support" + depends on ARCH_MX1 +diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c +index e94476b..2a822d9 100644 +--- a/drivers/mmc/host/atmel-mci.c ++++ b/drivers/mmc/host/atmel-mci.c +@@ -165,6 +165,7 @@ struct atmel_mci { + void __iomem *regs; + + struct scatterlist *sg; ++ unsigned int sg_len; + unsigned int pio_offset; + + struct atmel_mci_slot *cur_slot; +@@ -754,6 +755,7 @@ static u32 atmci_prepare_data(struct atmel_mci *host, struct mmc_data *data) + data->error = -EINPROGRESS; + + host->sg = data->sg; ++ host->sg_len = data->sg_len; + host->data = data; + host->data_chan = NULL; + +@@ -1592,7 +1594,8 @@ static void atmci_read_data_pio(struct atmel_mci *host) + if (offset == sg->length) { + flush_dcache_page(sg_page(sg)); + host->sg = sg = sg_next(sg); +- if (!sg) ++ host->sg_len--; ++ if (!sg || !host->sg_len) + goto done; + + offset = 0; +@@ -1605,7 +1608,8 @@ static void atmci_read_data_pio(struct atmel_mci *host) + + flush_dcache_page(sg_page(sg)); + host->sg = sg = sg_next(sg); +- if (!sg) ++ host->sg_len--; ++ if (!sg || !host->sg_len) + goto done; + + offset = 4 - remaining; +@@ -1659,7 +1663,8 @@ static void atmci_write_data_pio(struct atmel_mci *host) + nbytes += 4; + if (offset == sg->length) { + host->sg = sg = sg_next(sg); +- if (!sg) ++ host->sg_len--; ++ if (!sg || !host->sg_len) + goto done; + + offset = 0; +@@ -1673,7 +1678,8 @@ static void atmci_write_data_pio(struct atmel_mci *host) + nbytes += remaining; + + host->sg = sg = sg_next(sg); +- if (!sg) { ++ host->sg_len--; ++ if (!sg || !host->sg_len) { + atmci_writel(host, ATMCI_TDR, value); + goto done; + } +@@ -2190,10 +2196,8 @@ static int __exit atmci_remove(struct platform_device *pdev) + atmci_readl(host, ATMCI_SR); + clk_disable(host->mck); + +-#ifdef CONFIG_MMC_ATMELMCI_DMA + if (host->dma.chan) + dma_release_channel(host->dma.chan); +-#endif + + free_irq(platform_get_irq(pdev, 0), host); + iounmap(host->regs); +diff --git a/drivers/net/ethernet/freescale/gianfar_ptp.c b/drivers/net/ethernet/freescale/gianfar_ptp.c +index 5fd620b..ca2748a 100644 +--- a/drivers/net/ethernet/freescale/gianfar_ptp.c ++++ b/drivers/net/ethernet/freescale/gianfar_ptp.c +@@ -127,7 +127,6 @@ struct gianfar_ptp_registers { + + #define DRIVER "gianfar_ptp" + #define DEFAULT_CKSEL 1 +-#define N_ALARM 1 /* first alarm is used internally to reset fipers */ + #define N_EXT_TS 2 + #define REG_SIZE sizeof(struct gianfar_ptp_registers) + +@@ -410,7 +409,7 @@ static struct ptp_clock_info ptp_gianfar_caps = { + .owner = THIS_MODULE, + .name = "gianfar clock", + .max_adj = 512000, +- .n_alarm = N_ALARM, ++ .n_alarm = 0, + .n_ext_ts = N_EXT_TS, + .n_per_out = 0, + .pps = 1, +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +index 6d1f6c5..8f95545 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +@@ -2263,6 +2263,16 @@ static irqreturn_t ixgbe_msix_other(int irq, void *data) + * with the write to EICR. + */ + eicr = IXGBE_READ_REG(hw, IXGBE_EICS); ++ ++ /* The lower 16bits of the EICR register are for the queue interrupts ++ * which should be masked here in order to not accidently clear them if ++ * the bits are high when ixgbe_msix_other is called. There is a race ++ * condition otherwise which results in possible performance loss ++ * especially if the ixgbe_msix_other interrupt is triggering ++ * consistently (as it would when PPS is turned on for the X540 device) ++ */ ++ eicr &= 0xFFFF0000; ++ + IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr); + + if (eicr & IXGBE_EICR_LSC) +diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c +index 9abb8f5..59e946a 100644 +--- a/drivers/net/wireless/mwifiex/pcie.c ++++ b/drivers/net/wireless/mwifiex/pcie.c +@@ -1828,9 +1828,9 @@ static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter) + if (pdev) { + pci_iounmap(pdev, card->pci_mmap); + pci_iounmap(pdev, card->pci_mmap1); +- +- pci_release_regions(pdev); + pci_disable_device(pdev); ++ pci_release_region(pdev, 2); ++ pci_release_region(pdev, 0); + pci_set_drvdata(pdev, NULL); + } + } +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index 111569c..d08c0d8 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -673,15 +673,11 @@ static int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state) + error = platform_pci_set_power_state(dev, state); + if (!error) + pci_update_current_state(dev, state); +- /* Fall back to PCI_D0 if native PM is not supported */ +- if (!dev->pm_cap) +- dev->current_state = PCI_D0; +- } else { ++ } else + error = -ENODEV; +- /* Fall back to PCI_D0 if native PM is not supported */ +- if (!dev->pm_cap) +- dev->current_state = PCI_D0; +- } ++ ++ if (error && !dev->pm_cap) /* Fall back to PCI_D0 */ ++ dev->current_state = PCI_D0; + + return error; + } +diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c +index 7d5f56e..5f8844c 100644 +--- a/drivers/rtc/rtc-cmos.c ++++ b/drivers/rtc/rtc-cmos.c +@@ -805,9 +805,8 @@ static int cmos_suspend(struct device *dev) + mask = RTC_IRQMASK; + tmp &= ~mask; + CMOS_WRITE(tmp, RTC_CONTROL); ++ hpet_mask_rtc_irq_bit(mask); + +- /* shut down hpet emulation - we don't need it for alarm */ +- hpet_mask_rtc_irq_bit(RTC_PIE|RTC_AIE|RTC_UIE); + cmos_checkintr(cmos, tmp); + } + spin_unlock_irq(&rtc_lock); +@@ -872,6 +871,7 @@ static int cmos_resume(struct device *dev) + rtc_update_irq(cmos->rtc, 1, mask); + tmp &= ~RTC_AIE; + hpet_mask_rtc_irq_bit(RTC_AIE); ++ hpet_rtc_timer_init(); + } while (mask & RTC_AIE); + spin_unlock_irq(&rtc_lock); + } +diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c +index 231a1d8..e73b219 100644 +--- a/drivers/s390/char/sclp_cmd.c ++++ b/drivers/s390/char/sclp_cmd.c +@@ -509,6 +509,8 @@ static void __init sclp_add_standby_memory(void) + add_memory_merged(0); + } + ++#define MEM_SCT_SIZE (1UL << SECTION_SIZE_BITS) ++ + static void __init insert_increment(u16 rn, int standby, int assigned) + { + struct memory_increment *incr, *new_incr; +@@ -521,7 +523,7 @@ static void __init insert_increment(u16 rn, int standby, int assigned) + new_incr->rn = rn; + new_incr->standby = standby; + if (!standby) +- new_incr->usecount = 1; ++ new_incr->usecount = rzm > MEM_SCT_SIZE ? rzm/MEM_SCT_SIZE : 1; + last_rn = 0; + prev = &sclp_mem_list; + list_for_each_entry(incr, &sclp_mem_list, list) { +diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c +index 636c539..cf9a191 100644 +--- a/drivers/tty/pty.c ++++ b/drivers/tty/pty.c +@@ -607,6 +607,9 @@ static int ptmx_open(struct inode *inode, struct file *filp) + + nonseekable_open(inode, filp); + ++ /* We refuse fsnotify events on ptmx, since it's a shared resource */ ++ filp->f_mode |= FMODE_NONOTIFY; ++ + retval = tty_alloc_file(filp); + if (retval) + return retval; +diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c +index 246b823..4185cc5 100644 +--- a/drivers/tty/serial/serial_core.c ++++ b/drivers/tty/serial/serial_core.c +@@ -1877,6 +1877,8 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) + mutex_unlock(&port->mutex); + return 0; + } ++ put_device(tty_dev); ++ + if (console_suspend_enabled || !uart_console(uport)) + uport->suspended = 1; + +@@ -1942,9 +1944,11 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) + disable_irq_wake(uport->irq); + uport->irq_wake = 0; + } ++ put_device(tty_dev); + mutex_unlock(&port->mutex); + return 0; + } ++ put_device(tty_dev); + uport->suspended = 0; + + /* +diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c +index bf9f987..b28d635 100644 +--- a/drivers/tty/tty_io.c ++++ b/drivers/tty/tty_io.c +@@ -938,10 +938,10 @@ void start_tty(struct tty_struct *tty) + + EXPORT_SYMBOL(start_tty); + ++/* We limit tty time update visibility to every 8 seconds or so. */ + static void tty_update_time(struct timespec *time) + { +- unsigned long sec = get_seconds(); +- sec -= sec % 60; ++ unsigned long sec = get_seconds() & ~7; + if ((long)(sec - time->tv_sec) > 0) + time->tv_sec = sec; + } +diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c +index 404413b..336b82d 100644 +--- a/drivers/usb/core/devio.c ++++ b/drivers/usb/core/devio.c +@@ -681,6 +681,8 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, + index &= 0xff; + switch (requesttype & USB_RECIP_MASK) { + case USB_RECIP_ENDPOINT: ++ if ((index & ~USB_DIR_IN) == 0) ++ return 0; + ret = findintfep(ps->dev, index); + if (ret >= 0) + ret = checkintf(ps, ret); +diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c +index ac0d75a..9f7003e 100644 +--- a/drivers/usb/misc/appledisplay.c ++++ b/drivers/usb/misc/appledisplay.c +@@ -63,6 +63,7 @@ static const struct usb_device_id appledisplay_table[] = { + { APPLEDISPLAY_DEVICE(0x9219) }, + { APPLEDISPLAY_DEVICE(0x921c) }, + { APPLEDISPLAY_DEVICE(0x921d) }, ++ { APPLEDISPLAY_DEVICE(0x9236) }, + + /* Terminating entry */ + { } +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index 07a4fb0..e5ccafc 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -197,6 +197,7 @@ static struct usb_device_id id_table_combined [] = { + { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_THROTTLE_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GATEWAY_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_PID) }, ++ { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_BOOST_PID) }, + { USB_DEVICE(NEWPORT_VID, NEWPORT_AGILIS_PID) }, + { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, + { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, +@@ -878,7 +879,9 @@ static struct usb_device_id id_table_combined [] = { + { USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) }, + { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, +- { USB_DEVICE(ST_VID, ST_STMCLT1030_PID), ++ { USB_DEVICE(ST_VID, ST_STMCLT_2232_PID), ++ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, ++ { USB_DEVICE(ST_VID, ST_STMCLT_4232_PID), + .driver_info = (kernel_ulong_t)&ftdi_stmclite_quirk }, + { USB_DEVICE(FTDI_VID, FTDI_RF_R106) }, + { USB_DEVICE(FTDI_VID, FTDI_DISTORTEC_JTAG_LOCK_PICK_PID), +diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h +index e79861e..9852827 100644 +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -74,6 +74,7 @@ + #define FTDI_OPENDCC_THROTTLE_PID 0xBFDA + #define FTDI_OPENDCC_GATEWAY_PID 0xBFDB + #define FTDI_OPENDCC_GBM_PID 0xBFDC ++#define FTDI_OPENDCC_GBM_BOOST_PID 0xBFDD + + /* NZR SEM 16+ USB (http://www.nzr.de) */ + #define FTDI_NZR_SEM_USB_PID 0xC1E0 /* NZR SEM-LOG16+ */ +@@ -1150,7 +1151,8 @@ + * STMicroelectonics + */ + #define ST_VID 0x0483 +-#define ST_STMCLT1030_PID 0x3747 /* ST Micro Connect Lite STMCLT1030 */ ++#define ST_STMCLT_2232_PID 0x3746 ++#define ST_STMCLT_4232_PID 0x3747 + + /* + * Papouch products (http://www.papouch.com/) +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 78c4774..16efe0a 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -347,6 +347,7 @@ static void option_instat_callback(struct urb *urb); + /* Olivetti products */ + #define OLIVETTI_VENDOR_ID 0x0b3c + #define OLIVETTI_PRODUCT_OLICARD100 0xc000 ++#define OLIVETTI_PRODUCT_OLICARD145 0xc003 + + /* Celot products */ + #define CELOT_VENDOR_ID 0x211f +@@ -1273,6 +1274,7 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, + + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, ++ { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD145) }, + { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ + { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP 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.*/ +@@ -1350,6 +1352,12 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { 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) */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x02, 0x01) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x00, 0x00) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x02, 0x01) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) }, + { } /* Terminating entry */ + }; + MODULE_DEVICE_TABLE(usb, option_ids); +diff --git a/drivers/usb/storage/cypress_atacb.c b/drivers/usb/storage/cypress_atacb.c +index 5fe451d..c1f6751 100644 +--- a/drivers/usb/storage/cypress_atacb.c ++++ b/drivers/usb/storage/cypress_atacb.c +@@ -248,14 +248,26 @@ static int cypress_probe(struct usb_interface *intf, + { + struct us_data *us; + int result; ++ struct usb_device *device; + + result = usb_stor_probe1(&us, intf, id, + (id - cypress_usb_ids) + cypress_unusual_dev_list); + if (result) + return result; + +- us->protocol_name = "Transparent SCSI with Cypress ATACB"; +- us->proto_handler = cypress_atacb_passthrough; ++ /* Among CY7C68300 chips, the A revision does not support Cypress ATACB ++ * Filter out this revision from EEPROM default descriptor values ++ */ ++ device = interface_to_usbdev(intf); ++ if (device->descriptor.iManufacturer != 0x38 || ++ device->descriptor.iProduct != 0x4e || ++ device->descriptor.iSerialNumber != 0x64) { ++ us->protocol_name = "Transparent SCSI with Cypress ATACB"; ++ us->proto_handler = cypress_atacb_passthrough; ++ } else { ++ us->protocol_name = "Transparent SCSI"; ++ us->proto_handler = usb_stor_transparent_scsi_command; ++ } + + result = usb_stor_probe2(us); + return result; +diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c +index 18ded2d..a01317c 100644 +--- a/drivers/video/console/fbcon.c ++++ b/drivers/video/console/fbcon.c +@@ -1228,6 +1228,8 @@ static void fbcon_deinit(struct vc_data *vc) + finished: + + fbcon_free_font(p, free_font); ++ if (free_font) ++ vc->vc_font.data = NULL; + + if (!con_is_bound(&fb_con)) + fbcon_exit(); +diff --git a/fs/dcache.c b/fs/dcache.c +index f104945..e498de2 100644 +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -1238,8 +1238,10 @@ void shrink_dcache_parent(struct dentry * parent) + LIST_HEAD(dispose); + int found; + +- while ((found = select_parent(parent, &dispose)) != 0) ++ while ((found = select_parent(parent, &dispose)) != 0) { + shrink_dentry_list(&dispose); ++ cond_resched(); ++ } + } + EXPORT_SYMBOL(shrink_dcache_parent); + +diff --git a/fs/exec.c b/fs/exec.c +index e3a7e36d..2b7f5ff 100644 +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -627,7 +627,7 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) + * when the old and new regions overlap clear from new_end. + */ + free_pgd_range(&tlb, new_end, old_end, new_end, +- vma->vm_next ? vma->vm_next->vm_start : 0); ++ vma->vm_next ? vma->vm_next->vm_start : USER_PGTABLES_CEILING); + } else { + /* + * otherwise, clean from old_start; this is done to not touch +@@ -636,7 +636,7 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) + * for the others its just a little faster. + */ + free_pgd_range(&tlb, old_start, old_end, new_end, +- vma->vm_next ? vma->vm_next->vm_start : 0); ++ vma->vm_next ? vma->vm_next->vm_start : USER_PGTABLES_CEILING); + } + tlb_finish_mmu(&tlb, new_end, old_end); + +diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig +index 9ed1bb1..5459168 100644 +--- a/fs/ext4/Kconfig ++++ b/fs/ext4/Kconfig +@@ -82,4 +82,5 @@ config EXT4_DEBUG + Enables run-time debugging support for the ext4 filesystem. + + If you select Y here, then you will be able to turn on debugging +- with a command such as "echo 1 > /sys/kernel/debug/ext4/mballoc-debug" ++ with a command such as: ++ echo 1 > /sys/module/ext4/parameters/mballoc_debug +diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h +index 83b20fc..6b23a96 100644 +--- a/fs/ext4/ext4_jbd2.h ++++ b/fs/ext4/ext4_jbd2.h +@@ -164,16 +164,20 @@ static inline void ext4_journal_callback_add(handle_t *handle, + * ext4_journal_callback_del: delete a registered callback + * @handle: active journal transaction handle on which callback was registered + * @jce: registered journal callback entry to unregister ++ * Return true if object was sucessfully removed + */ +-static inline void ext4_journal_callback_del(handle_t *handle, ++static inline bool ext4_journal_callback_try_del(handle_t *handle, + struct ext4_journal_cb_entry *jce) + { ++ bool deleted; + struct ext4_sb_info *sbi = + EXT4_SB(handle->h_transaction->t_journal->j_private); + + spin_lock(&sbi->s_md_lock); ++ deleted = !list_empty(&jce->jce_list); + list_del_init(&jce->jce_list); + spin_unlock(&sbi->s_md_lock); ++ return deleted; + } + + int +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index 6c32dd8..ec970cb 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -4436,11 +4436,11 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b, + node = rb_prev(new_node); + if (node) { + entry = rb_entry(node, struct ext4_free_data, efd_node); +- if (can_merge(entry, new_entry)) { ++ if (can_merge(entry, new_entry) && ++ ext4_journal_callback_try_del(handle, &entry->efd_jce)) { + new_entry->efd_start_cluster = entry->efd_start_cluster; + new_entry->efd_count += entry->efd_count; + rb_erase(node, &(db->bb_free_root)); +- ext4_journal_callback_del(handle, &entry->efd_jce); + kmem_cache_free(ext4_free_data_cachep, entry); + } + } +@@ -4448,10 +4448,10 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b, + node = rb_next(new_node); + if (node) { + entry = rb_entry(node, struct ext4_free_data, efd_node); +- if (can_merge(new_entry, entry)) { ++ if (can_merge(new_entry, entry) && ++ ext4_journal_callback_try_del(handle, &entry->efd_jce)) { + new_entry->efd_count += entry->efd_count; + rb_erase(node, &(db->bb_free_root)); +- ext4_journal_callback_del(handle, &entry->efd_jce); + kmem_cache_free(ext4_free_data_cachep, entry); + } + } +diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c +index 3fc0e8b..9202b22 100644 +--- a/fs/ext4/resize.c ++++ b/fs/ext4/resize.c +@@ -1202,6 +1202,8 @@ static void ext4_update_super(struct super_block *sb, + + /* Update the global fs size fields */ + sbi->s_groups_count += flex_gd->count; ++ sbi->s_blockfile_groups = min_t(ext4_group_t, sbi->s_groups_count, ++ (EXT4_MAX_BLOCK_FILE_PHYS / EXT4_BLOCKS_PER_GROUP(sb))); + + /* Update the reserved block counts only once the new group is + * active. */ +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 88bb68d..b93de81 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -437,10 +437,13 @@ static void ext4_journal_commit_callback(journal_t *journal, transaction_t *txn) + struct super_block *sb = journal->j_private; + struct ext4_sb_info *sbi = EXT4_SB(sb); + int error = is_journal_aborted(journal); +- struct ext4_journal_cb_entry *jce, *tmp; ++ struct ext4_journal_cb_entry *jce; + ++ BUG_ON(txn->t_state == T_FINISHED); + spin_lock(&sbi->s_md_lock); +- list_for_each_entry_safe(jce, tmp, &txn->t_private_list, jce_list) { ++ while (!list_empty(&txn->t_private_list)) { ++ jce = list_entry(txn->t_private_list.next, ++ struct ext4_journal_cb_entry, jce_list); + list_del_init(&jce->jce_list); + spin_unlock(&sbi->s_md_lock); + jce->jce_func(sb, jce, error); +diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c +index 4765190..73c0bd7 100644 +--- a/fs/fscache/stats.c ++++ b/fs/fscache/stats.c +@@ -276,5 +276,5 @@ const struct file_operations fscache_stats_fops = { + .open = fscache_stats_open, + .read = seq_read, + .llseek = seq_lseek, +- .release = seq_release, ++ .release = single_release, + }; +diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c +index 840f70f..a0dcbd62 100644 +--- a/fs/jbd2/commit.c ++++ b/fs/jbd2/commit.c +@@ -325,7 +325,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) + int space_left = 0; + int first_tag = 0; + int tag_flag; +- int i, to_free = 0; ++ int i; + int tag_bytes = journal_tag_bytes(journal); + struct buffer_head *cbh = NULL; /* For transactional checksums */ + __u32 crc32_sum = ~0; +@@ -1044,7 +1044,7 @@ restart_loop: + journal->j_stats.run.rs_blocks_logged += stats.run.rs_blocks_logged; + spin_unlock(&journal->j_history_lock); + +- commit_transaction->t_state = T_FINISHED; ++ commit_transaction->t_state = T_COMMIT_CALLBACK; + J_ASSERT(commit_transaction == journal->j_committing_transaction); + journal->j_commit_sequence = commit_transaction->t_tid; + journal->j_committing_transaction = NULL; +@@ -1059,38 +1059,44 @@ restart_loop: + journal->j_average_commit_time*3) / 4; + else + journal->j_average_commit_time = commit_time; ++ + write_unlock(&journal->j_state_lock); + +- if (commit_transaction->t_checkpoint_list == NULL && +- commit_transaction->t_checkpoint_io_list == NULL) { +- __jbd2_journal_drop_transaction(journal, commit_transaction); +- to_free = 1; ++ if (journal->j_checkpoint_transactions == NULL) { ++ journal->j_checkpoint_transactions = commit_transaction; ++ commit_transaction->t_cpnext = commit_transaction; ++ commit_transaction->t_cpprev = commit_transaction; + } else { +- if (journal->j_checkpoint_transactions == NULL) { +- journal->j_checkpoint_transactions = commit_transaction; +- commit_transaction->t_cpnext = commit_transaction; +- commit_transaction->t_cpprev = commit_transaction; +- } else { +- commit_transaction->t_cpnext = +- journal->j_checkpoint_transactions; +- commit_transaction->t_cpprev = +- commit_transaction->t_cpnext->t_cpprev; +- commit_transaction->t_cpnext->t_cpprev = +- commit_transaction; +- commit_transaction->t_cpprev->t_cpnext = ++ commit_transaction->t_cpnext = ++ journal->j_checkpoint_transactions; ++ commit_transaction->t_cpprev = ++ commit_transaction->t_cpnext->t_cpprev; ++ commit_transaction->t_cpnext->t_cpprev = ++ commit_transaction; ++ commit_transaction->t_cpprev->t_cpnext = + commit_transaction; +- } + } + spin_unlock(&journal->j_list_lock); +- ++ /* Drop all spin_locks because commit_callback may be block. ++ * __journal_remove_checkpoint() can not destroy transaction ++ * under us because it is not marked as T_FINISHED yet */ + if (journal->j_commit_callback) + journal->j_commit_callback(journal, commit_transaction); + + trace_jbd2_end_commit(journal, commit_transaction); + jbd_debug(1, "JBD2: commit %d complete, head %d\n", + journal->j_commit_sequence, journal->j_tail_sequence); +- if (to_free) +- jbd2_journal_free_transaction(commit_transaction); + ++ write_lock(&journal->j_state_lock); ++ spin_lock(&journal->j_list_lock); ++ commit_transaction->t_state = T_FINISHED; ++ /* Recheck checkpoint lists after j_list_lock was dropped */ ++ if (commit_transaction->t_checkpoint_list == NULL && ++ commit_transaction->t_checkpoint_io_list == NULL) { ++ __jbd2_journal_drop_transaction(journal, commit_transaction); ++ jbd2_journal_free_transaction(commit_transaction); ++ } ++ spin_unlock(&journal->j_list_lock); ++ write_unlock(&journal->j_state_lock); + wake_up(&journal->j_wait_done_commit); + } +diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c +index ca0a080..193f04c 100644 +--- a/fs/lockd/clntlock.c ++++ b/fs/lockd/clntlock.c +@@ -144,6 +144,9 @@ int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout) + timeout); + if (ret < 0) + return -ERESTARTSYS; ++ /* Reset the lock status after a server reboot so we resend */ ++ if (block->b_status == nlm_lck_denied_grace_period) ++ block->b_status = nlm_lck_blocked; + req->a_res.status = block->b_status; + return 0; + } +diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c +index a3a0987..8392cb8 100644 +--- a/fs/lockd/clntproc.c ++++ b/fs/lockd/clntproc.c +@@ -551,9 +551,6 @@ again: + status = nlmclnt_block(block, req, NLMCLNT_POLL_TIMEOUT); + if (status < 0) + break; +- /* Resend the blocking lock request after a server reboot */ +- if (resp->status == nlm_lck_denied_grace_period) +- continue; + if (resp->status != nlm_lck_blocked) + break; + } +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 3035187..04f449c 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -1362,6 +1362,12 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state + case -ENOMEM: + err = 0; + goto out; ++ case -NFS4ERR_DELAY: ++ case -NFS4ERR_GRACE: ++ set_bit(NFS_DELEGATED_STATE, &state->flags); ++ ssleep(1); ++ err = -EAGAIN; ++ goto out; + } + err = nfs4_handle_exception(server, err, &exception); + } while (exception.retry); +diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c +index abd785e..f90b197 100644 +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -213,13 +213,7 @@ static void __nfs4_file_put_access(struct nfs4_file *fp, int oflag) + { + if (atomic_dec_and_test(&fp->fi_access[oflag])) { + nfs4_file_put_fd(fp, oflag); +- /* +- * It's also safe to get rid of the RDWR open *if* +- * we no longer have need of the other kind of access +- * or if we already have the other kind of open: +- */ +- if (fp->fi_fds[1-oflag] +- || atomic_read(&fp->fi_access[1 - oflag]) == 0) ++ if (atomic_read(&fp->fi_access[1 - oflag]) == 0) + nfs4_file_put_fd(fp, O_RDWR); + } + } +diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c +index ace6745..1798846 100644 +--- a/fs/nfsd/nfs4xdr.c ++++ b/fs/nfsd/nfs4xdr.c +@@ -343,10 +343,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, + all 32 bits of 'nseconds'. */ + READ_BUF(12); + len += 12; +- READ32(dummy32); +- if (dummy32) +- return nfserr_inval; +- READ32(iattr->ia_atime.tv_sec); ++ READ64(iattr->ia_atime.tv_sec); + READ32(iattr->ia_atime.tv_nsec); + if (iattr->ia_atime.tv_nsec >= (u32)1000000000) + return nfserr_inval; +@@ -369,10 +366,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, + all 32 bits of 'nseconds'. */ + READ_BUF(12); + len += 12; +- READ32(dummy32); +- if (dummy32) +- return nfserr_inval; +- READ32(iattr->ia_mtime.tv_sec); ++ READ64(iattr->ia_mtime.tv_sec); + READ32(iattr->ia_mtime.tv_nsec); + if (iattr->ia_mtime.tv_nsec >= (u32)1000000000) + return nfserr_inval; +@@ -2371,8 +2365,7 @@ out_acl: + if (bmval1 & FATTR4_WORD1_TIME_ACCESS) { + if ((buflen -= 12) < 0) + goto out_resource; +- WRITE32(0); +- WRITE32(stat.atime.tv_sec); ++ WRITE64((s64)stat.atime.tv_sec); + WRITE32(stat.atime.tv_nsec); + } + if (bmval1 & FATTR4_WORD1_TIME_DELTA) { +@@ -2385,15 +2378,13 @@ out_acl: + if (bmval1 & FATTR4_WORD1_TIME_METADATA) { + if ((buflen -= 12) < 0) + goto out_resource; +- WRITE32(0); +- WRITE32(stat.ctime.tv_sec); ++ WRITE64((s64)stat.ctime.tv_sec); + WRITE32(stat.ctime.tv_nsec); + } + if (bmval1 & FATTR4_WORD1_TIME_MODIFY) { + if ((buflen -= 12) < 0) + goto out_resource; +- WRITE32(0); +- WRITE32(stat.mtime.tv_sec); ++ WRITE64((s64)stat.mtime.tv_sec); + WRITE32(stat.mtime.tv_nsec); + } + if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) { +diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c +index 45024ef..9a5f07d 100644 +--- a/fs/sysfs/dir.c ++++ b/fs/sysfs/dir.c +@@ -994,6 +994,7 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) + enum kobj_ns_type type; + const void *ns; + ino_t ino; ++ loff_t off; + + type = sysfs_ns_type(parent_sd); + ns = sysfs_info(dentry->d_sb)->ns[type]; +@@ -1016,6 +1017,7 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) + return 0; + } + mutex_lock(&sysfs_mutex); ++ off = filp->f_pos; + for (pos = sysfs_dir_pos(ns, parent_sd, filp->f_pos, pos); + pos; + pos = sysfs_dir_next_pos(ns, parent_sd, filp->f_pos, pos)) { +@@ -1027,19 +1029,24 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) + len = strlen(name); + ino = pos->s_ino; + type = dt_type(pos); +- filp->f_pos = pos->s_hash; ++ off = filp->f_pos = pos->s_hash; + filp->private_data = sysfs_get(pos); + + mutex_unlock(&sysfs_mutex); +- ret = filldir(dirent, name, len, filp->f_pos, ino, type); ++ ret = filldir(dirent, name, len, off, ino, type); + mutex_lock(&sysfs_mutex); + if (ret < 0) + break; + } + mutex_unlock(&sysfs_mutex); +- if ((filp->f_pos > 1) && !pos) { /* EOF */ +- filp->f_pos = INT_MAX; ++ ++ /* don't reference last entry if its refcount is dropped */ ++ if (!pos) { + filp->private_data = NULL; ++ ++ /* EOF and not changed as 0 or 1 in read/write path */ ++ if (off == filp->f_pos && off > 1) ++ filp->f_pos = INT_MAX; + } + return 0; + } +diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h +index c7ec2cd..9a6eb25 100644 +--- a/include/asm-generic/pgtable.h ++++ b/include/asm-generic/pgtable.h +@@ -7,6 +7,16 @@ + #include + #include + ++/* ++ * On almost all architectures and configurations, 0 can be used as the ++ * upper ceiling to free_pgtables(): on many architectures it has the same ++ * effect as using TASK_SIZE. However, there is one configuration which ++ * must impose a more careful limit, to avoid freeing kernel pgtables. ++ */ ++#ifndef USER_PGTABLES_CEILING ++#define USER_PGTABLES_CEILING 0UL ++#endif ++ + #ifndef __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS + extern int ptep_set_access_flags(struct vm_area_struct *vma, + unsigned long address, pte_t *ptep, +diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h +index 8a297a5..497c6cc 100644 +--- a/include/linux/ipc_namespace.h ++++ b/include/linux/ipc_namespace.h +@@ -42,8 +42,8 @@ struct ipc_namespace { + + size_t shm_ctlmax; + size_t shm_ctlall; ++ unsigned long shm_tot; + int shm_ctlmni; +- int shm_tot; + /* + * Defines whether IPC_RMID is forced for _all_ shm segments regardless + * of shmctl() +diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h +index 2ed66ef..dd6444f 100644 +--- a/include/linux/jbd2.h ++++ b/include/linux/jbd2.h +@@ -470,6 +470,7 @@ struct transaction_s + T_COMMIT, + T_COMMIT_DFLUSH, + T_COMMIT_JFLUSH, ++ T_COMMIT_CALLBACK, + T_FINISHED + } t_state; + +diff --git a/ipc/shm.c b/ipc/shm.c +index 406c5b2..85d81b4 100644 +--- a/ipc/shm.c ++++ b/ipc/shm.c +@@ -450,7 +450,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) + size_t size = params->u.size; + int error; + struct shmid_kernel *shp; +- int numpages = (size + PAGE_SIZE -1) >> PAGE_SHIFT; ++ size_t numpages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; + struct file * file; + char name[13]; + int id; +diff --git a/kernel/cgroup.c b/kernel/cgroup.c +index a4c47d1b..4eb1ed3 100644 +--- a/kernel/cgroup.c ++++ b/kernel/cgroup.c +@@ -2020,7 +2020,7 @@ static int cgroup_attach_proc(struct cgroup *cgrp, struct task_struct *leader) + if (!group) + return -ENOMEM; + /* pre-allocate to guarantee space while iterating in rcu read-side. */ +- retval = flex_array_prealloc(group, 0, group_size - 1, GFP_KERNEL); ++ retval = flex_array_prealloc(group, 0, group_size, GFP_KERNEL); + if (retval) + goto out_free_group_list; + +diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c +index e4cee8d..60f7e32 100644 +--- a/kernel/hrtimer.c ++++ b/kernel/hrtimer.c +@@ -298,6 +298,10 @@ ktime_t ktime_sub_ns(const ktime_t kt, u64 nsec) + } else { + unsigned long rem = do_div(nsec, NSEC_PER_SEC); + ++ /* Make sure nsec fits into long */ ++ if (unlikely(nsec > KTIME_SEC_MAX)) ++ return (ktime_t){ .tv64 = KTIME_MAX }; ++ + tmp = ktime_set((long)nsec, rem); + } + +@@ -1308,6 +1312,8 @@ retry: + + expires = ktime_sub(hrtimer_get_expires(timer), + base->offset); ++ if (expires.tv64 < 0) ++ expires.tv64 = KTIME_MAX; + if (expires.tv64 < expires_next.tv64) + expires_next = expires; + break; +diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c +index a13987a..239a323 100644 +--- a/kernel/time/tick-broadcast.c ++++ b/kernel/time/tick-broadcast.c +@@ -66,6 +66,8 @@ static void tick_broadcast_start_periodic(struct clock_event_device *bc) + */ + int tick_check_broadcast_device(struct clock_event_device *dev) + { ++ struct clock_event_device *cur = tick_broadcast_device.evtdev; ++ + if ((dev->features & CLOCK_EVT_FEAT_DUMMY) || + (tick_broadcast_device.evtdev && + tick_broadcast_device.evtdev->rating >= dev->rating) || +@@ -73,6 +75,8 @@ int tick_check_broadcast_device(struct clock_event_device *dev) + return 0; + + clockevents_exchange_device(tick_broadcast_device.evtdev, dev); ++ if (cur) ++ cur->event_handler = clockevents_handle_noop; + tick_broadcast_device.evtdev = dev; + if (!cpumask_empty(tick_get_broadcast_mask())) + tick_broadcast_start_periodic(dev); +diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c +index da6c9ec..ead79bc 100644 +--- a/kernel/time/tick-common.c ++++ b/kernel/time/tick-common.c +@@ -323,6 +323,7 @@ static void tick_shutdown(unsigned int *cpup) + */ + dev->mode = CLOCK_EVT_MODE_UNUSED; + clockevents_exchange_device(dev, NULL); ++ dev->event_handler = clockevents_handle_noop; + td->evtdev = NULL; + } + raw_spin_unlock_irqrestore(&tick_device_lock, flags); +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index a3c1dd9..c962d31 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -624,7 +624,7 @@ int ftrace_profile_pages_init(struct ftrace_profile_stat *stat) + + pages = DIV_ROUND_UP(functions, PROFILES_PER_PAGE); + +- for (i = 0; i < pages; i++) { ++ for (i = 1; i < pages; i++) { + pg->next = (void *)get_zeroed_page(GFP_KERNEL); + if (!pg->next) + goto out_free; +@@ -3611,7 +3611,8 @@ out: + if (fail) + return -EINVAL; + +- ftrace_graph_filter_enabled = 1; ++ ftrace_graph_filter_enabled = !!(*idx); ++ + return 0; + } + +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index 8beda39..b29ebd3 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -4717,6 +4717,8 @@ static __init int tracer_init_debugfs(void) + trace_access_lock_init(); + + d_tracer = tracing_init_dentry(); ++ if (!d_tracer) ++ return 0; + + trace_create_file("tracing_enabled", 0644, d_tracer, + &global_trace, &tracing_ctrl_fops); +diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c +index d4545f4..c70f6bf 100644 +--- a/kernel/trace/trace_stack.c ++++ b/kernel/trace/trace_stack.c +@@ -20,13 +20,24 @@ + + #define STACK_TRACE_ENTRIES 500 + ++#ifdef CC_USING_FENTRY ++# define fentry 1 ++#else ++# define fentry 0 ++#endif ++ + static unsigned long stack_dump_trace[STACK_TRACE_ENTRIES+1] = + { [0 ... (STACK_TRACE_ENTRIES)] = ULONG_MAX }; + static unsigned stack_dump_index[STACK_TRACE_ENTRIES]; + ++/* ++ * Reserve one entry for the passed in ip. This will allow ++ * us to remove most or all of the stack size overhead ++ * added by the stack tracer itself. ++ */ + static struct stack_trace max_stack_trace = { +- .max_entries = STACK_TRACE_ENTRIES, +- .entries = stack_dump_trace, ++ .max_entries = STACK_TRACE_ENTRIES - 1, ++ .entries = &stack_dump_trace[1], + }; + + static unsigned long max_stack_size; +@@ -40,25 +51,34 @@ static DEFINE_MUTEX(stack_sysctl_mutex); + int stack_tracer_enabled; + static int last_stack_tracer_enabled; + +-static inline void check_stack(void) ++static inline void ++check_stack(unsigned long ip, unsigned long *stack) + { + unsigned long this_size, flags; + unsigned long *p, *top, *start; ++ static int tracer_frame; ++ int frame_size = ACCESS_ONCE(tracer_frame); + int i; + +- this_size = ((unsigned long)&this_size) & (THREAD_SIZE-1); ++ this_size = ((unsigned long)stack) & (THREAD_SIZE-1); + this_size = THREAD_SIZE - this_size; ++ /* Remove the frame of the tracer */ ++ this_size -= frame_size; + + if (this_size <= max_stack_size) + return; + + /* we do not handle interrupt stacks yet */ +- if (!object_is_on_stack(&this_size)) ++ if (!object_is_on_stack(stack)) + return; + + local_irq_save(flags); + arch_spin_lock(&max_stack_lock); + ++ /* In case another CPU set the tracer_frame on us */ ++ if (unlikely(!frame_size)) ++ this_size -= tracer_frame; ++ + /* a race could have already updated it */ + if (this_size <= max_stack_size) + goto out; +@@ -71,10 +91,18 @@ static inline void check_stack(void) + save_stack_trace(&max_stack_trace); + + /* ++ * Add the passed in ip from the function tracer. ++ * Searching for this on the stack will skip over ++ * most of the overhead from the stack tracer itself. ++ */ ++ stack_dump_trace[0] = ip; ++ max_stack_trace.nr_entries++; ++ ++ /* + * Now find where in the stack these are. + */ + i = 0; +- start = &this_size; ++ start = stack; + top = (unsigned long *) + (((unsigned long)start & ~(THREAD_SIZE-1)) + THREAD_SIZE); + +@@ -98,6 +126,18 @@ static inline void check_stack(void) + found = 1; + /* Start the search from here */ + start = p + 1; ++ /* ++ * We do not want to show the overhead ++ * of the stack tracer stack in the ++ * max stack. If we haven't figured ++ * out what that is, then figure it out ++ * now. ++ */ ++ if (unlikely(!tracer_frame) && i == 1) { ++ tracer_frame = (p - stack) * ++ sizeof(unsigned long); ++ max_stack_size -= tracer_frame; ++ } + } + } + +@@ -113,6 +153,7 @@ static inline void check_stack(void) + static void + stack_trace_call(unsigned long ip, unsigned long parent_ip) + { ++ unsigned long stack; + int cpu; + + if (unlikely(!ftrace_enabled || stack_trace_disabled)) +@@ -125,7 +166,26 @@ stack_trace_call(unsigned long ip, unsigned long parent_ip) + if (per_cpu(trace_active, cpu)++ != 0) + goto out; + +- check_stack(); ++ /* ++ * When fentry is used, the traced function does not get ++ * its stack frame set up, and we lose the parent. ++ * The ip is pretty useless because the function tracer ++ * was called before that function set up its stack frame. ++ * In this case, we use the parent ip. ++ * ++ * By adding the return address of either the parent ip ++ * or the current ip we can disregard most of the stack usage ++ * caused by the stack tracer itself. ++ * ++ * The function tracer always reports the address of where the ++ * mcount call was, but the stack will hold the return address. ++ */ ++ if (fentry) ++ ip = parent_ip; ++ else ++ ip += MCOUNT_INSN_SIZE; ++ ++ check_stack(ip, &stack); + + out: + per_cpu(trace_active, cpu)--; +@@ -373,6 +433,8 @@ static __init int stack_trace_init(void) + struct dentry *d_tracer; + + d_tracer = tracing_init_dentry(); ++ if (!d_tracer) ++ return 0; + + trace_create_file("stack_max_size", 0644, d_tracer, + &max_stack_size, &stack_max_size_fops); +diff --git a/kernel/trace/trace_stat.c b/kernel/trace/trace_stat.c +index 96cffb2..847f88a 100644 +--- a/kernel/trace/trace_stat.c ++++ b/kernel/trace/trace_stat.c +@@ -307,6 +307,8 @@ static int tracing_stat_init(void) + struct dentry *d_tracing; + + d_tracing = tracing_init_dentry(); ++ if (!d_tracing) ++ return 0; + + stat_dir = debugfs_create_dir("trace_stat", d_tracing); + if (!stat_dir) +diff --git a/mm/mmap.c b/mm/mmap.c +index 2add0a1..3635d47 100644 +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -1920,7 +1920,7 @@ static void unmap_region(struct mm_struct *mm, + unmap_vmas(&tlb, vma, start, end, &nr_accounted, NULL); + vm_unacct_memory(nr_accounted); + free_pgtables(&tlb, vma, prev ? prev->vm_end : FIRST_USER_ADDRESS, +- next ? next->vm_start : 0); ++ next ? next->vm_start : USER_PGTABLES_CEILING); + tlb_finish_mmu(&tlb, start, end); + } + +@@ -2308,7 +2308,7 @@ void exit_mmap(struct mm_struct *mm) + unmap_vmas(&tlb, vma, 0, -1, &nr_accounted, NULL); + vm_unacct_memory(nr_accounted); + +- free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, 0); ++ free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, USER_PGTABLES_CEILING); + tlb_finish_mmu(&tlb, 0, -1); + + /* +diff --git a/net/wireless/reg.c b/net/wireless/reg.c +index 4dc8347..796a0ee 100644 +--- a/net/wireless/reg.c ++++ b/net/wireless/reg.c +@@ -862,7 +862,7 @@ static void handle_channel(struct wiphy *wiphy, + return; + + REG_DBG_PRINT("Disabling freq %d MHz\n", chan->center_freq); +- chan->flags = IEEE80211_CHAN_DISABLED; ++ chan->flags |= IEEE80211_CHAN_DISABLED; + return; + } + +diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c +index af7324b..4790568 100644 +--- a/sound/soc/codecs/max98088.c ++++ b/sound/soc/codecs/max98088.c +@@ -2006,7 +2006,7 @@ static int max98088_probe(struct snd_soc_codec *codec) + ret); + goto err_access; + } +- dev_info(codec->dev, "revision %c\n", ret + 'A'); ++ dev_info(codec->dev, "revision %c\n", ret - 0x40 + 'A'); + + snd_soc_write(codec, M98088_REG_51_PWR_SYS, M98088_PWRSV); + +diff --git a/sound/usb/card.c b/sound/usb/card.c +index 388460d..b41730d 100644 +--- a/sound/usb/card.c ++++ b/sound/usb/card.c +@@ -611,7 +611,9 @@ int snd_usb_autoresume(struct snd_usb_audio *chip) + int err = -ENODEV; + + down_read(&chip->shutdown_rwsem); +- if (!chip->shutdown && !chip->probing) ++ if (chip->probing) ++ err = 0; ++ else if (!chip->shutdown) + err = usb_autopm_get_interface(chip->pm_intf); + up_read(&chip->shutdown_rwsem); + +diff --git a/sound/usb/midi.c b/sound/usb/midi.c +index 34b9bb7..e5fee18 100644 +--- a/sound/usb/midi.c ++++ b/sound/usb/midi.c +@@ -126,7 +126,6 @@ struct snd_usb_midi { + struct snd_usb_midi_in_endpoint *in; + } endpoints[MIDI_MAX_ENDPOINTS]; + unsigned long input_triggered; +- bool autopm_reference; + unsigned int opened[2]; + unsigned char disconnected; + unsigned char input_running; +@@ -1040,7 +1039,6 @@ static int substream_open(struct snd_rawmidi_substream *substream, int dir, + { + struct snd_usb_midi* umidi = substream->rmidi->private_data; + struct snd_kcontrol *ctl; +- int err; + + down_read(&umidi->disc_rwsem); + if (umidi->disconnected) { +@@ -1051,13 +1049,6 @@ static int substream_open(struct snd_rawmidi_substream *substream, int dir, + mutex_lock(&umidi->mutex); + if (open) { + if (!umidi->opened[0] && !umidi->opened[1]) { +- err = usb_autopm_get_interface(umidi->iface); +- umidi->autopm_reference = err >= 0; +- if (err < 0 && err != -EACCES) { +- mutex_unlock(&umidi->mutex); +- up_read(&umidi->disc_rwsem); +- return -EIO; +- } + if (umidi->roland_load_ctl) { + ctl = umidi->roland_load_ctl; + ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; +@@ -1080,8 +1071,6 @@ static int substream_open(struct snd_rawmidi_substream *substream, int dir, + snd_ctl_notify(umidi->card, + SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); + } +- if (umidi->autopm_reference) +- usb_autopm_put_interface(umidi->iface); + } + } + mutex_unlock(&umidi->mutex); +@@ -2256,6 +2245,8 @@ int snd_usbmidi_create(struct snd_card *card, + return err; + } + ++ usb_autopm_get_interface_no_resume(umidi->iface); ++ + list_add_tail(&umidi->list, midi_list); + return 0; + } +diff --git a/sound/usb/stream.c b/sound/usb/stream.c +index 5ff8010..33a335b 100644 +--- a/sound/usb/stream.c ++++ b/sound/usb/stream.c +@@ -168,6 +168,14 @@ static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip, + if (!csep && altsd->bNumEndpoints >= 2) + csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT); + ++ /* ++ * If we can't locate the USB_DT_CS_ENDPOINT descriptor in the extra ++ * bytes after the first endpoint, go search the entire interface. ++ * Some devices have it directly *before* the standard endpoint. ++ */ ++ if (!csep) ++ csep = snd_usb_find_desc(alts->extra, alts->extralen, NULL, USB_DT_CS_ENDPOINT); ++ + if (!csep || csep->bLength < 7 || + csep->bDescriptorSubtype != UAC_EP_GENERAL) { + snd_printk(KERN_WARNING "%d:%u:%d : no or invalid" diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.44-45.patch b/patch/kernel/sun8i-default/0001-patch-3.4.44-45.patch new file mode 100644 index 000000000..1c7cbf4df --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.44-45.patch @@ -0,0 +1,909 @@ +diff --git a/Makefile b/Makefile +index c156161..0ec4a35 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 44 ++SUBLEVEL = 45 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h +index d81f994..762f7a6 100644 +--- a/arch/powerpc/include/asm/ppc-opcode.h ++++ b/arch/powerpc/include/asm/ppc-opcode.h +@@ -45,6 +45,10 @@ + #define PPC_INST_MFSPR_DSCR_MASK 0xfc1fffff + #define PPC_INST_MTSPR_DSCR 0x7c1103a6 + #define PPC_INST_MTSPR_DSCR_MASK 0xfc1fffff ++#define PPC_INST_MFSPR_DSCR_USER 0x7c0302a6 ++#define PPC_INST_MFSPR_DSCR_USER_MASK 0xfc1fffff ++#define PPC_INST_MTSPR_DSCR_USER 0x7c0303a6 ++#define PPC_INST_MTSPR_DSCR_USER_MASK 0xfc1fffff + #define PPC_INST_SLBFEE 0x7c0007a7 + + #define PPC_INST_STRING 0x7c00042a +diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c +index ae0843f..3bb7197 100644 +--- a/arch/powerpc/kernel/traps.c ++++ b/arch/powerpc/kernel/traps.c +@@ -960,7 +960,10 @@ static int emulate_instruction(struct pt_regs *regs) + + #ifdef CONFIG_PPC64 + /* Emulate the mfspr rD, DSCR. */ +- if (((instword & PPC_INST_MFSPR_DSCR_MASK) == PPC_INST_MFSPR_DSCR) && ++ if ((((instword & PPC_INST_MFSPR_DSCR_USER_MASK) == ++ PPC_INST_MFSPR_DSCR_USER) || ++ ((instword & PPC_INST_MFSPR_DSCR_MASK) == ++ PPC_INST_MFSPR_DSCR)) && + cpu_has_feature(CPU_FTR_DSCR)) { + PPC_WARN_EMULATED(mfdscr, regs); + rd = (instword >> 21) & 0x1f; +@@ -968,7 +971,10 @@ static int emulate_instruction(struct pt_regs *regs) + return 0; + } + /* Emulate the mtspr DSCR, rD. */ +- if (((instword & PPC_INST_MTSPR_DSCR_MASK) == PPC_INST_MTSPR_DSCR) && ++ if ((((instword & PPC_INST_MTSPR_DSCR_USER_MASK) == ++ PPC_INST_MTSPR_DSCR_USER) || ++ ((instword & PPC_INST_MTSPR_DSCR_MASK) == ++ PPC_INST_MTSPR_DSCR)) && + cpu_has_feature(CPU_FTR_DSCR)) { + PPC_WARN_EMULATED(mtdscr, regs); + rd = (instword >> 21) & 0x1f; +diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c +index 6e8f677..6130719 100644 +--- a/arch/powerpc/mm/numa.c ++++ b/arch/powerpc/mm/numa.c +@@ -201,7 +201,7 @@ int __node_distance(int a, int b) + int distance = LOCAL_DISTANCE; + + if (!form1_affinity) +- return distance; ++ return ((a == b) ? LOCAL_DISTANCE : REMOTE_DISTANCE); + + for (i = 0; i < distance_ref_points_depth; i++) { + if (distance_lookup_table[a][i] == distance_lookup_table[b][i]) +diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c +index 520b426..fd1a099 100644 +--- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c ++++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c +@@ -310,7 +310,7 @@ void intel_pmu_lbr_read(void) + * - in case there is no HW filter + * - in case the HW filter has errata or limitations + */ +-static void intel_pmu_setup_sw_lbr_filter(struct perf_event *event) ++static int intel_pmu_setup_sw_lbr_filter(struct perf_event *event) + { + u64 br_type = event->attr.branch_sample_type; + int mask = 0; +@@ -318,8 +318,11 @@ static void intel_pmu_setup_sw_lbr_filter(struct perf_event *event) + if (br_type & PERF_SAMPLE_BRANCH_USER) + mask |= X86_BR_USER; + +- if (br_type & PERF_SAMPLE_BRANCH_KERNEL) ++ if (br_type & PERF_SAMPLE_BRANCH_KERNEL) { ++ if (perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN)) ++ return -EACCES; + mask |= X86_BR_KERNEL; ++ } + + /* we ignore BRANCH_HV here */ + +@@ -339,6 +342,8 @@ static void intel_pmu_setup_sw_lbr_filter(struct perf_event *event) + * be used by fixup code for some CPU + */ + event->hw.branch_reg.reg = mask; ++ ++ return 0; + } + + /* +@@ -386,7 +391,9 @@ int intel_pmu_setup_lbr_filter(struct perf_event *event) + /* + * setup SW LBR filter + */ +- intel_pmu_setup_sw_lbr_filter(event); ++ ret = intel_pmu_setup_sw_lbr_filter(event); ++ if (ret) ++ return ret; + + /* + * setup HW LBR filter, if any +@@ -442,8 +449,18 @@ static int branch_type(unsigned long from, unsigned long to) + return X86_BR_NONE; + + addr = buf; +- } else +- addr = (void *)from; ++ } else { ++ /* ++ * The LBR logs any address in the IP, even if the IP just ++ * faulted. This means userspace can control the from address. ++ * Ensure we don't blindy read any address by validating it is ++ * a known text address. ++ */ ++ if (kernel_text_address(from)) ++ addr = (void *)from; ++ else ++ return X86_BR_NONE; ++ } + + /* + * decoder needs to know the ABI especially +diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c +index fae7090..71d37f5 100644 +--- a/arch/x86/mm/init.c ++++ b/arch/x86/mm/init.c +@@ -45,11 +45,15 @@ static void __init find_early_table_space(struct map_range *mr, int nr_range) + int i; + unsigned long puds = 0, pmds = 0, ptes = 0, tables; + unsigned long start = 0, good_end; ++ unsigned long pgd_extra = 0; + phys_addr_t base; + + for (i = 0; i < nr_range; i++) { + unsigned long range, extra; + ++ if ((mr[i].end >> PGDIR_SHIFT) - (mr[i].start >> PGDIR_SHIFT)) ++ pgd_extra++; ++ + range = mr[i].end - mr[i].start; + puds += (range + PUD_SIZE - 1) >> PUD_SHIFT; + +@@ -74,6 +78,7 @@ static void __init find_early_table_space(struct map_range *mr, int nr_range) + tables = roundup(puds * sizeof(pud_t), PAGE_SIZE); + tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE); + tables += roundup(ptes * sizeof(pte_t), PAGE_SIZE); ++ tables += (pgd_extra * PAGE_SIZE); + + #ifdef CONFIG_X86_32 + /* for fixmap */ +diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c +index 53ddbc7..0bf5bd1 100644 +--- a/drivers/cpufreq/longhaul.c ++++ b/drivers/cpufreq/longhaul.c +@@ -77,7 +77,7 @@ static unsigned int longhaul_index; + static int scale_voltage; + static int disable_acpi_c3; + static int revid_errata; +- ++static int enable; + + /* Clock ratios multiplied by 10 */ + static int mults[32]; +@@ -965,6 +965,10 @@ static int __init longhaul_init(void) + if (!x86_match_cpu(longhaul_id)) + return -ENODEV; + ++ if (!enable) { ++ printk(KERN_ERR PFX "Option \"enable\" not set. Aborting.\n"); ++ return -ENODEV; ++ } + #ifdef CONFIG_SMP + if (num_online_cpus() > 1) { + printk(KERN_ERR PFX "More than 1 CPU detected, " +@@ -1021,6 +1025,10 @@ MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor"); + * such. */ + module_param(revid_errata, int, 0644); + MODULE_PARM_DESC(revid_errata, "Ignore CPU Revision ID"); ++/* By default driver is disabled to prevent incompatible ++ * system freeze. */ ++module_param(enable, int, 0644); ++MODULE_PARM_DESC(enable, "Enable driver"); + + MODULE_AUTHOR("Dave Jones "); + MODULE_DESCRIPTION("Longhaul driver for VIA Cyrix processors."); +diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c +index 020a7d7..69bea56 100644 +--- a/drivers/gpu/drm/i915/intel_dvo.c ++++ b/drivers/gpu/drm/i915/intel_dvo.c +@@ -370,6 +370,7 @@ void intel_dvo_init(struct drm_device *dev) + const struct intel_dvo_device *dvo = &intel_dvo_devices[i]; + struct i2c_adapter *i2c; + int gpio; ++ bool dvoinit; + + /* Allow the I2C driver info to specify the GPIO to be used in + * special cases, but otherwise default to what's defined +@@ -389,7 +390,17 @@ void intel_dvo_init(struct drm_device *dev) + i2c = &dev_priv->gmbus[gpio].adapter; + + intel_dvo->dev = *dvo; +- if (!dvo->dev_ops->init(&intel_dvo->dev, i2c)) ++ ++ /* GMBUS NAK handling seems to be unstable, hence let the ++ * transmitter detection run in bit banging mode for now. ++ */ ++ intel_gmbus_force_bit(i2c, true); ++ ++ dvoinit = dvo->dev_ops->init(&intel_dvo->dev, i2c); ++ ++ intel_gmbus_force_bit(i2c, false); ++ ++ if (!dvoinit) + continue; + + intel_encoder->type = INTEL_OUTPUT_DVO; +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index a8b28c4..1ad5906 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -793,6 +793,14 @@ static const struct dmi_system_id intel_no_lvds[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "X7SPA-H"), + }, + }, ++ { ++ .callback = intel_no_lvds_dmi_callback, ++ .ident = "Fujitsu Esprimo Q900", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Q900"), ++ }, ++ }, + + { } /* terminating entry */ + }; +diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c +index 5ce9bf5..43672b6 100644 +--- a/drivers/gpu/drm/radeon/atom.c ++++ b/drivers/gpu/drm/radeon/atom.c +@@ -1389,10 +1389,10 @@ int atom_allocate_fb_scratch(struct atom_context *ctx) + firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset); + + DRM_DEBUG("atom firmware requested %08x %dkb\n", +- firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware, +- firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb); ++ le32_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware), ++ le16_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb)); + +- usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024; ++ usage_bytes = le16_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb) * 1024; + } + ctx->scratch_size_bytes = 0; + if (usage_bytes == 0) +diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c +index c62132c..e458acb 100644 +--- a/drivers/gpu/drm/radeon/evergreen.c ++++ b/drivers/gpu/drm/radeon/evergreen.c +@@ -445,6 +445,16 @@ void evergreen_hpd_init(struct radeon_device *rdev) + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + struct radeon_connector *radeon_connector = to_radeon_connector(connector); ++ ++ if (connector->connector_type == DRM_MODE_CONNECTOR_eDP || ++ connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { ++ /* don't try to enable hpd on eDP or LVDS avoid breaking the ++ * aux dp channel on imac and help (but not completely fix) ++ * https://bugzilla.redhat.com/show_bug.cgi?id=726143 ++ * also avoid interrupt storms during dpms. ++ */ ++ continue; ++ } + switch (radeon_connector->hpd.hpd) { + case RADEON_HPD_1: + WREG32(DC_HPD1_CONTROL, tmp); +@@ -1146,17 +1156,16 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav + tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]); + if (!(tmp & EVERGREEN_CRTC_BLANK_DATA_EN)) { + radeon_wait_for_vblank(rdev, i); +- tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); ++ tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; + WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp); +- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0); + } + } else { + tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]); + if (!(tmp & EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE)) { + radeon_wait_for_vblank(rdev, i); +- tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE; + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); ++ tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE; + WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0); + } +@@ -1168,6 +1177,15 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav + break; + udelay(1); + } ++ ++ /* XXX this is a hack to avoid strange behavior with EFI on certain systems */ ++ WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); ++ tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]); ++ tmp &= ~EVERGREEN_CRTC_MASTER_EN; ++ WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp); ++ WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0); ++ save->crtc_enabled[i] = false; ++ /* ***** */ + } else { + save->crtc_enabled[i] = false; + } +@@ -1185,6 +1203,22 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav + } + /* wait for the MC to settle */ + udelay(100); ++ ++ /* lock double buffered regs */ ++ for (i = 0; i < rdev->num_crtc; i++) { ++ if (save->crtc_enabled[i]) { ++ tmp = RREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i]); ++ if (!(tmp & EVERGREEN_GRPH_UPDATE_LOCK)) { ++ tmp |= EVERGREEN_GRPH_UPDATE_LOCK; ++ WREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i], tmp); ++ } ++ tmp = RREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i]); ++ if (!(tmp & 1)) { ++ tmp |= 1; ++ WREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i], tmp); ++ } ++ } ++ } + } + + void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) +@@ -1206,6 +1240,33 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s + WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start); + ++ /* unlock regs and wait for update */ ++ for (i = 0; i < rdev->num_crtc; i++) { ++ if (save->crtc_enabled[i]) { ++ tmp = RREG32(EVERGREEN_MASTER_UPDATE_MODE + crtc_offsets[i]); ++ if ((tmp & 0x3) != 0) { ++ tmp &= ~0x3; ++ WREG32(EVERGREEN_MASTER_UPDATE_MODE + crtc_offsets[i], tmp); ++ } ++ tmp = RREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i]); ++ if (tmp & EVERGREEN_GRPH_UPDATE_LOCK) { ++ tmp &= ~EVERGREEN_GRPH_UPDATE_LOCK; ++ WREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i], tmp); ++ } ++ tmp = RREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i]); ++ if (tmp & 1) { ++ tmp &= ~1; ++ WREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i], tmp); ++ } ++ for (j = 0; j < rdev->usec_timeout; j++) { ++ tmp = RREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i]); ++ if ((tmp & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING) == 0) ++ break; ++ udelay(1); ++ } ++ } ++ } ++ + /* unblackout the MC */ + tmp = RREG32(MC_SHARED_BLACKOUT_CNTL); + tmp &= ~BLACKOUT_MODE_MASK; +diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h +index 34a0e85..e534e5d 100644 +--- a/drivers/gpu/drm/radeon/evergreen_reg.h ++++ b/drivers/gpu/drm/radeon/evergreen_reg.h +@@ -225,6 +225,8 @@ + #define EVERGREEN_CRTC_STATUS_POSITION 0x6e90 + #define EVERGREEN_MASTER_UPDATE_MODE 0x6ef8 + #define EVERGREEN_CRTC_UPDATE_LOCK 0x6ed4 ++#define EVERGREEN_MASTER_UPDATE_LOCK 0x6ef4 ++#define EVERGREEN_MASTER_UPDATE_MODE 0x6ef8 + + #define EVERGREEN_DC_GPIO_HPD_MASK 0x64b0 + #define EVERGREEN_DC_GPIO_HPD_A 0x64b4 +diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c +index 7dffc57..d706da8 100644 +--- a/drivers/gpu/drm/radeon/ni.c ++++ b/drivers/gpu/drm/radeon/ni.c +@@ -668,7 +668,8 @@ static void cayman_gpu_init(struct radeon_device *rdev) + (rdev->pdev->device == 0x990F) || + (rdev->pdev->device == 0x9910) || + (rdev->pdev->device == 0x9917) || +- (rdev->pdev->device == 0x9999)) { ++ (rdev->pdev->device == 0x9999) || ++ (rdev->pdev->device == 0x999C)) { + rdev->config.cayman.max_simds_per_se = 6; + rdev->config.cayman.max_backends_per_se = 2; + } else if ((rdev->pdev->device == 0x9903) || +@@ -677,7 +678,8 @@ static void cayman_gpu_init(struct radeon_device *rdev) + (rdev->pdev->device == 0x990D) || + (rdev->pdev->device == 0x990E) || + (rdev->pdev->device == 0x9913) || +- (rdev->pdev->device == 0x9918)) { ++ (rdev->pdev->device == 0x9918) || ++ (rdev->pdev->device == 0x999D)) { + rdev->config.cayman.max_simds_per_se = 4; + rdev->config.cayman.max_backends_per_se = 2; + } else if ((rdev->pdev->device == 0x9919) || +@@ -911,6 +913,8 @@ static void cayman_gpu_init(struct radeon_device *rdev) + WREG32(GB_BACKEND_MAP, gb_backend_map); + WREG32(GB_ADDR_CONFIG, gb_addr_config); + WREG32(DMIF_ADDR_CONFIG, gb_addr_config); ++ if (ASIC_IS_DCE6(rdev)) ++ WREG32(DMIF_ADDR_CALC, gb_addr_config); + WREG32(HDP_ADDR_CONFIG, gb_addr_config); + + /* primary versions */ +diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h +index 2aa7046..d90b8b7 100644 +--- a/drivers/gpu/drm/radeon/nid.h ++++ b/drivers/gpu/drm/radeon/nid.h +@@ -42,6 +42,10 @@ + #define CAYMAN_MAX_TCC_MASK 0xFF + + #define DMIF_ADDR_CONFIG 0xBD4 ++ ++/* DCE6 only */ ++#define DMIF_ADDR_CALC 0xC00 ++ + #define SRBM_GFX_CNTL 0x0E44 + #define RINGID(x) (((x) & 0x3) << 0) + #define VMID(x) (((x) & 0x7) << 0) +diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c +index 5e30e12..38d87e1 100644 +--- a/drivers/gpu/drm/radeon/radeon_atombios.c ++++ b/drivers/gpu/drm/radeon/radeon_atombios.c +@@ -1998,6 +1998,8 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev) + num_modes = power_info->info.ucNumOfPowerModeEntries; + if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK) + num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; ++ if (num_modes == 0) ++ return state_index; + rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * num_modes, GFP_KERNEL); + if (!rdev->pm.power_state) + return state_index; +@@ -2396,6 +2398,8 @@ static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev) + power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); + + radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController); ++ if (power_info->pplib.ucNumStates == 0) ++ return state_index; + rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * + power_info->pplib.ucNumStates, GFP_KERNEL); + if (!rdev->pm.power_state) +@@ -2478,6 +2482,7 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev) + int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); + u16 data_offset; + u8 frev, crev; ++ u8 *power_state_offset; + + if (!atom_parse_data_header(mode_info->atom_context, index, NULL, + &frev, &crev, &data_offset)) +@@ -2494,15 +2499,17 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev) + non_clock_info_array = (struct _NonClockInfoArray *) + (mode_info->atom_context->bios + data_offset + + le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); ++ if (state_array->ucNumEntries == 0) ++ return state_index; + rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * + state_array->ucNumEntries, GFP_KERNEL); + if (!rdev->pm.power_state) + return state_index; ++ power_state_offset = (u8 *)state_array->states; + for (i = 0; i < state_array->ucNumEntries; i++) { + mode_index = 0; +- power_state = (union pplib_power_state *)&state_array->states[i]; +- /* XXX this might be an inagua bug... */ +- non_clock_array_index = i; /* power_state->v2.nonClockInfoIndex */ ++ power_state = (union pplib_power_state *)power_state_offset; ++ non_clock_array_index = power_state->v2.nonClockInfoIndex; + non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) + &non_clock_info_array->nonClockInfo[non_clock_array_index]; + rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) * +@@ -2514,9 +2521,6 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev) + if (power_state->v2.ucNumDPMLevels) { + for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) { + clock_array_index = power_state->v2.clockInfoIndex[j]; +- /* XXX this might be an inagua bug... */ +- if (clock_array_index >= clock_info_array->ucNumEntries) +- continue; + clock_info = (union pplib_clock_info *) + &clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize]; + valid = radeon_atombios_parse_pplib_clock_info(rdev, +@@ -2538,6 +2542,7 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev) + non_clock_info); + state_index++; + } ++ power_state_offset += 2 + power_state->v2.ucNumDPMLevels; + } + /* if multiple clock modes, mark the lowest as no display */ + for (i = 0; i < state_index; i++) { +@@ -2584,7 +2589,9 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) + default: + break; + } +- } else { ++ } ++ ++ if (state_index == 0) { + rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL); + if (rdev->pm.power_state) { + rdev->pm.power_state[0].clock_info = +diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c +index b8459bd..bf6ca2d 100644 +--- a/drivers/gpu/drm/radeon/radeon_pm.c ++++ b/drivers/gpu/drm/radeon/radeon_pm.c +@@ -872,7 +872,11 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data) + struct radeon_device *rdev = dev->dev_private; + + seq_printf(m, "default engine clock: %u0 kHz\n", rdev->pm.default_sclk); +- seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev)); ++ /* radeon_get_engine_clock is not reliable on APUs so just print the current clock */ ++ if ((rdev->family >= CHIP_PALM) && (rdev->flags & RADEON_IS_IGP)) ++ seq_printf(m, "current engine clock: %u0 kHz\n", rdev->pm.current_sclk); ++ else ++ seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev)); + seq_printf(m, "default memory clock: %u0 kHz\n", rdev->pm.default_mclk); + if (rdev->asic->pm.get_memory_clock) + seq_printf(m, "current memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev)); +diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c +index 1197f21..5508ad7 100644 +--- a/drivers/gpu/drm/radeon/si.c ++++ b/drivers/gpu/drm/radeon/si.c +@@ -1799,6 +1799,7 @@ static void si_gpu_init(struct radeon_device *rdev) + rdev->config.si.backend_map = gb_backend_map; + WREG32(GB_ADDR_CONFIG, gb_addr_config); + WREG32(DMIF_ADDR_CONFIG, gb_addr_config); ++ WREG32(DMIF_ADDR_CALC, gb_addr_config); + WREG32(HDP_ADDR_CONFIG, gb_addr_config); + + /* primary versions */ +diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h +index 2c2bc63..45e240d 100644 +--- a/drivers/gpu/drm/radeon/sid.h ++++ b/drivers/gpu/drm/radeon/sid.h +@@ -55,6 +55,8 @@ + + #define DMIF_ADDR_CONFIG 0xBD4 + ++#define DMIF_ADDR_CALC 0xC00 ++ + #define SRBM_STATUS 0xE50 + + #define CC_SYS_RB_BACKEND_DISABLE 0xe80 +diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c +index b68d28a..33a1760 100644 +--- a/drivers/net/ethernet/ibm/ibmveth.c ++++ b/drivers/net/ethernet/ibm/ibmveth.c +@@ -1327,7 +1327,7 @@ static const struct net_device_ops ibmveth_netdev_ops = { + static int __devinit ibmveth_probe(struct vio_dev *dev, + const struct vio_device_id *id) + { +- int rc, i; ++ int rc, i, mac_len; + struct net_device *netdev; + struct ibmveth_adapter *adapter; + unsigned char *mac_addr_p; +@@ -1337,11 +1337,19 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, + dev->unit_address); + + mac_addr_p = (unsigned char *)vio_get_attribute(dev, VETH_MAC_ADDR, +- NULL); ++ &mac_len); + if (!mac_addr_p) { + dev_err(&dev->dev, "Can't find VETH_MAC_ADDR attribute\n"); + return -EINVAL; + } ++ /* Workaround for old/broken pHyp */ ++ if (mac_len == 8) ++ mac_addr_p += 2; ++ else if (mac_len != 6) { ++ dev_err(&dev->dev, "VETH_MAC_ADDR attribute wrong len %d\n", ++ mac_len); ++ return -EINVAL; ++ } + + mcastFilterSize_p = (unsigned int *)vio_get_attribute(dev, + VETH_MCAST_FILTER_SIZE, NULL); +@@ -1366,17 +1374,6 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, + + netif_napi_add(netdev, &adapter->napi, ibmveth_poll, 16); + +- /* +- * Some older boxes running PHYP non-natively have an OF that returns +- * a 8-byte local-mac-address field (and the first 2 bytes have to be +- * ignored) while newer boxes' OF return a 6-byte field. Note that +- * IEEE 1275 specifies that local-mac-address must be a 6-byte field. +- * The RPA doc specifies that the first byte must be 10b, so we'll +- * just look for it to solve this 8 vs. 6 byte field issue +- */ +- if ((*mac_addr_p & 0x3) != 0x02) +- mac_addr_p += 2; +- + adapter->mac_addr = 0; + memcpy(&adapter->mac_addr, mac_addr_p, 6); + +diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c +index 978af21..dd037dd 100644 +--- a/drivers/net/ethernet/realtek/r8169.c ++++ b/drivers/net/ethernet/realtek/r8169.c +@@ -5168,6 +5168,14 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, + goto err_stop_0; + } + ++ /* 8168evl does not automatically pad to minimum length. */ ++ if (unlikely(tp->mac_version == RTL_GIGA_MAC_VER_34 && ++ skb->len < ETH_ZLEN)) { ++ if (skb_padto(skb, ETH_ZLEN)) ++ goto err_update_stats; ++ skb_put(skb, ETH_ZLEN - skb->len); ++ } ++ + if (unlikely(le32_to_cpu(txd->opts1) & DescOwn)) + goto err_stop_0; + +@@ -5239,6 +5247,7 @@ err_dma_1: + rtl8169_unmap_tx_skb(d, tp->tx_skb + entry, txd); + err_dma_0: + dev_kfree_skb(skb); ++err_update_stats: + dev->stats.tx_dropped++; + return NETDEV_TX_OK; + +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index a3c9374..843b3e8 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -2459,14 +2459,21 @@ static int handle_tx_event(struct xhci_hcd *xhci, + * TD list. + */ + if (list_empty(&ep_ring->td_list)) { +- xhci_warn(xhci, "WARN Event TRB for slot %d ep %d " +- "with no TDs queued?\n", +- TRB_TO_SLOT_ID(le32_to_cpu(event->flags)), +- ep_index); +- xhci_dbg(xhci, "Event TRB with TRB type ID %u\n", +- (le32_to_cpu(event->flags) & +- TRB_TYPE_BITMASK)>>10); +- xhci_print_trb_offsets(xhci, (union xhci_trb *) event); ++ /* ++ * A stopped endpoint may generate an extra completion ++ * event if the device was suspended. Don't print ++ * warnings. ++ */ ++ if (!(trb_comp_code == COMP_STOP || ++ trb_comp_code == COMP_STOP_INVAL)) { ++ xhci_warn(xhci, "WARN Event TRB for slot %d ep %d with no TDs queued?\n", ++ TRB_TO_SLOT_ID(le32_to_cpu(event->flags)), ++ ep_index); ++ xhci_dbg(xhci, "Event TRB with TRB type ID %u\n", ++ (le32_to_cpu(event->flags) & ++ TRB_TYPE_BITMASK)>>10); ++ xhci_print_trb_offsets(xhci, (union xhci_trb *) event); ++ } + if (ep->skip) { + ep->skip = false; + xhci_dbg(xhci, "td_list is empty while skip " +diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c +index 1feb68e..b1cdb0a 100644 +--- a/fs/autofs4/expire.c ++++ b/fs/autofs4/expire.c +@@ -61,15 +61,6 @@ static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry) + /* This is an autofs submount, we can't expire it */ + if (autofs_type_indirect(sbi->type)) + goto done; +- +- /* +- * Otherwise it's an offset mount and we need to check +- * if we can umount its mount, if there is one. +- */ +- if (!d_mountpoint(path.dentry)) { +- status = 0; +- goto done; +- } + } + + /* Update the expiry counter if fs is busy */ +diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c +index 9202b22..86a8c88 100644 +--- a/fs/ext4/resize.c ++++ b/fs/ext4/resize.c +@@ -1630,6 +1630,10 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count) + return 0; + + ext4_get_group_no_and_offset(sb, n_blocks_count - 1, &n_group, &offset); ++ if (n_group > (0xFFFFFFFFUL / EXT4_INODES_PER_GROUP(sb))) { ++ ext4_warning(sb, "resize would cause inodes_count overflow"); ++ return -EINVAL; ++ } + ext4_get_group_no_and_offset(sb, o_blocks_count - 1, &o_group, &offset); + + n_desc_blocks = (n_group + EXT4_DESC_PER_BLOCK(sb)) / +diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h +index d9928c1..1a13caa 100644 +--- a/include/drm/drm_pciids.h ++++ b/include/drm/drm_pciids.h +@@ -231,6 +231,7 @@ + {0x1002, 0x6819, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6821, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x6822, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6823, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6824, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ +@@ -238,11 +239,13 @@ + {0x1002, 0x6827, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6828, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6829, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x682A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x682B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x682D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x682F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6830, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6831, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x6835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6837, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6838, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6839, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_NEW_MEMMAP}, \ +@@ -594,6 +597,8 @@ + {0x1002, 0x9999, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x999A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x999B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x999C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x999D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x99A0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x99A2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x99A4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ +diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c +index 31fdc48..0caf1f8 100644 +--- a/kernel/audit_tree.c ++++ b/kernel/audit_tree.c +@@ -608,9 +608,9 @@ void audit_trim_trees(void) + } + spin_unlock(&hash_lock); + trim_marked(tree); +- put_tree(tree); + drop_collected_mounts(root_mnt); + skip_it: ++ put_tree(tree); + mutex_lock(&audit_filter_mutex); + } + list_del(&cursor); +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index b29ebd3..75c11bf 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -4855,36 +4855,32 @@ void trace_init_global_iter(struct trace_iterator *iter) + iter->cpu_file = TRACE_PIPE_ALL_CPU; + } + +-static void +-__ftrace_dump(bool disable_tracing, enum ftrace_dump_mode oops_dump_mode) ++void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) + { +- static arch_spinlock_t ftrace_dump_lock = +- (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; + /* use static because iter can be a bit big for the stack */ + static struct trace_iterator iter; ++ static atomic_t dump_running; + unsigned int old_userobj; +- static int dump_ran; + unsigned long flags; + int cnt = 0, cpu; + +- /* only one dump */ +- local_irq_save(flags); +- arch_spin_lock(&ftrace_dump_lock); +- if (dump_ran) +- goto out; +- +- dump_ran = 1; ++ /* Only allow one dump user at a time. */ ++ if (atomic_inc_return(&dump_running) != 1) { ++ atomic_dec(&dump_running); ++ return; ++ } + ++ /* ++ * Always turn off tracing when we dump. ++ * We don't need to show trace output of what happens ++ * between multiple crashes. ++ * ++ * If the user does a sysrq-z, then they can re-enable ++ * tracing with echo 1 > tracing_on. ++ */ + tracing_off(); + +- /* Did function tracer already get disabled? */ +- if (ftrace_is_dead()) { +- printk("# WARNING: FUNCTION TRACING IS CORRUPTED\n"); +- printk("# MAY BE MISSING FUNCTION EVENTS\n"); +- } +- +- if (disable_tracing) +- ftrace_kill(); ++ local_irq_save(flags); + + trace_init_global_iter(&iter); + +@@ -4917,6 +4913,12 @@ __ftrace_dump(bool disable_tracing, enum ftrace_dump_mode oops_dump_mode) + + printk(KERN_TRACE "Dumping ftrace buffer:\n"); + ++ /* Did function tracer already get disabled? */ ++ if (ftrace_is_dead()) { ++ printk("# WARNING: FUNCTION TRACING IS CORRUPTED\n"); ++ printk("# MAY BE MISSING FUNCTION EVENTS\n"); ++ } ++ + /* + * We need to stop all tracing on all CPUS to read the + * the next buffer. This is a bit expensive, but is +@@ -4956,26 +4958,14 @@ __ftrace_dump(bool disable_tracing, enum ftrace_dump_mode oops_dump_mode) + printk(KERN_TRACE "---------------------------------\n"); + + out_enable: +- /* Re-enable tracing if requested */ +- if (!disable_tracing) { +- trace_flags |= old_userobj; ++ trace_flags |= old_userobj; + +- for_each_tracing_cpu(cpu) { +- atomic_dec(&iter.tr->data[cpu]->disabled); +- } +- tracing_on(); ++ for_each_tracing_cpu(cpu) { ++ atomic_dec(&iter.tr->data[cpu]->disabled); + } +- +- out: +- arch_spin_unlock(&ftrace_dump_lock); ++ atomic_dec(&dump_running); + local_irq_restore(flags); + } +- +-/* By default: disable tracing after the dump */ +-void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) +-{ +- __ftrace_dump(true, oops_dump_mode); +-} + EXPORT_SYMBOL_GPL(ftrace_dump); + + __init static int tracer_alloc_buffers(void) +diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c +index 288541f..09fd98a 100644 +--- a/kernel/trace/trace_selftest.c ++++ b/kernel/trace/trace_selftest.c +@@ -461,8 +461,6 @@ trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr) + /* Maximum number of functions to trace before diagnosing a hang */ + #define GRAPH_MAX_FUNC_TEST 100000000 + +-static void +-__ftrace_dump(bool disable_tracing, enum ftrace_dump_mode oops_dump_mode); + static unsigned int graph_hang_thresh; + + /* Wrap the real function entry probe to avoid possible hanging */ +@@ -472,8 +470,11 @@ static int trace_graph_entry_watchdog(struct ftrace_graph_ent *trace) + if (unlikely(++graph_hang_thresh > GRAPH_MAX_FUNC_TEST)) { + ftrace_graph_stop(); + printk(KERN_WARNING "BUG: Function graph tracer hang!\n"); +- if (ftrace_dump_on_oops) +- __ftrace_dump(false, DUMP_ALL); ++ if (ftrace_dump_on_oops) { ++ ftrace_dump(DUMP_ALL); ++ /* ftrace_dump() disables tracing */ ++ tracing_on(); ++ } + return 0; + } + +diff --git a/net/netfilter/ipvs/ip_vs_pe_sip.c b/net/netfilter/ipvs/ip_vs_pe_sip.c +index 1aa5cac..55add93 100644 +--- a/net/netfilter/ipvs/ip_vs_pe_sip.c ++++ b/net/netfilter/ipvs/ip_vs_pe_sip.c +@@ -37,14 +37,10 @@ static int get_callid(const char *dptr, unsigned int dataoff, + if (ret > 0) + break; + if (!ret) +- return 0; ++ return -EINVAL; + dataoff += *matchoff; + } + +- /* Empty callid is useless */ +- if (!*matchlen) +- return -EINVAL; +- + /* Too large is useless */ + if (*matchlen > IP_VS_PEDATA_MAXLEN) + return -EINVAL; diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.45-46.patch b/patch/kernel/sun8i-default/0001-patch-3.4.45-46.patch new file mode 100644 index 000000000..bf41d11c8 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.45-46.patch @@ -0,0 +1,1875 @@ +diff --git a/Makefile b/Makefile +index 0ec4a35..3d88eb8 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 45 ++SUBLEVEL = 46 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c +index d87ee06..283a8d0 100644 +--- a/arch/arm/mach-omap2/board-rx51-peripherals.c ++++ b/arch/arm/mach-omap2/board-rx51-peripherals.c +@@ -63,11 +63,11 @@ + #define RX51_TSC2005_RESET_GPIO 104 + #define RX51_TSC2005_IRQ_GPIO 100 + +-/* list all spi devices here */ ++/* List all SPI devices here. Note that the list/probe order seems to matter! */ + enum { + RX51_SPI_WL1251, +- RX51_SPI_MIPID, /* LCD panel */ + RX51_SPI_TSC2005, /* Touch Controller */ ++ RX51_SPI_MIPID, /* LCD panel */ + }; + + static struct wl12xx_platform_data wl1251_pdata; +diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h +index 557cff8..5e7e008 100644 +--- a/arch/powerpc/include/asm/rtas.h ++++ b/arch/powerpc/include/asm/rtas.h +@@ -262,6 +262,8 @@ extern void rtas_progress(char *s, unsigned short hex); + extern void rtas_initialize(void); + extern int rtas_suspend_cpu(struct rtas_suspend_me_data *data); + extern int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data); ++extern int rtas_online_cpus_mask(cpumask_var_t cpus); ++extern int rtas_offline_cpus_mask(cpumask_var_t cpus); + extern int rtas_ibm_suspend_me(struct rtas_args *); + + struct rtc_time; +diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c +index fcec382..225e9f2 100644 +--- a/arch/powerpc/kernel/rtas.c ++++ b/arch/powerpc/kernel/rtas.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -808,6 +809,95 @@ static void rtas_percpu_suspend_me(void *info) + __rtas_suspend_cpu((struct rtas_suspend_me_data *)info, 1); + } + ++enum rtas_cpu_state { ++ DOWN, ++ UP, ++}; ++ ++#ifndef CONFIG_SMP ++static int rtas_cpu_state_change_mask(enum rtas_cpu_state state, ++ cpumask_var_t cpus) ++{ ++ if (!cpumask_empty(cpus)) { ++ cpumask_clear(cpus); ++ return -EINVAL; ++ } else ++ return 0; ++} ++#else ++/* On return cpumask will be altered to indicate CPUs changed. ++ * CPUs with states changed will be set in the mask, ++ * CPUs with status unchanged will be unset in the mask. */ ++static int rtas_cpu_state_change_mask(enum rtas_cpu_state state, ++ cpumask_var_t cpus) ++{ ++ int cpu; ++ int cpuret = 0; ++ int ret = 0; ++ ++ if (cpumask_empty(cpus)) ++ return 0; ++ ++ for_each_cpu(cpu, cpus) { ++ switch (state) { ++ case DOWN: ++ cpuret = cpu_down(cpu); ++ break; ++ case UP: ++ cpuret = cpu_up(cpu); ++ break; ++ } ++ if (cpuret) { ++ pr_debug("%s: cpu_%s for cpu#%d returned %d.\n", ++ __func__, ++ ((state == UP) ? "up" : "down"), ++ cpu, cpuret); ++ if (!ret) ++ ret = cpuret; ++ if (state == UP) { ++ /* clear bits for unchanged cpus, return */ ++ cpumask_shift_right(cpus, cpus, cpu); ++ cpumask_shift_left(cpus, cpus, cpu); ++ break; ++ } else { ++ /* clear bit for unchanged cpu, continue */ ++ cpumask_clear_cpu(cpu, cpus); ++ } ++ } ++ } ++ ++ return ret; ++} ++#endif ++ ++int rtas_online_cpus_mask(cpumask_var_t cpus) ++{ ++ int ret; ++ ++ ret = rtas_cpu_state_change_mask(UP, cpus); ++ ++ if (ret) { ++ cpumask_var_t tmp_mask; ++ ++ if (!alloc_cpumask_var(&tmp_mask, GFP_TEMPORARY)) ++ return ret; ++ ++ /* Use tmp_mask to preserve cpus mask from first failure */ ++ cpumask_copy(tmp_mask, cpus); ++ rtas_offline_cpus_mask(tmp_mask); ++ free_cpumask_var(tmp_mask); ++ } ++ ++ return ret; ++} ++EXPORT_SYMBOL(rtas_online_cpus_mask); ++ ++int rtas_offline_cpus_mask(cpumask_var_t cpus) ++{ ++ return rtas_cpu_state_change_mask(DOWN, cpus); ++} ++EXPORT_SYMBOL(rtas_offline_cpus_mask); ++ + int rtas_ibm_suspend_me(struct rtas_args *args) + { + long state; +@@ -815,6 +905,8 @@ int rtas_ibm_suspend_me(struct rtas_args *args) + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; + struct rtas_suspend_me_data data; + DECLARE_COMPLETION_ONSTACK(done); ++ cpumask_var_t offline_mask; ++ int cpuret; + + if (!rtas_service_present("ibm,suspend-me")) + return -ENOSYS; +@@ -838,11 +930,24 @@ int rtas_ibm_suspend_me(struct rtas_args *args) + return 0; + } + ++ if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY)) ++ return -ENOMEM; ++ + atomic_set(&data.working, 0); + atomic_set(&data.done, 0); + atomic_set(&data.error, 0); + data.token = rtas_token("ibm,suspend-me"); + data.complete = &done; ++ ++ /* All present CPUs must be online */ ++ cpumask_andnot(offline_mask, cpu_present_mask, cpu_online_mask); ++ cpuret = rtas_online_cpus_mask(offline_mask); ++ if (cpuret) { ++ pr_err("%s: Could not bring present CPUs online.\n", __func__); ++ atomic_set(&data.error, cpuret); ++ goto out; ++ } ++ + stop_topology_update(); + + /* Call function on all CPUs. One of us will make the +@@ -858,6 +963,14 @@ int rtas_ibm_suspend_me(struct rtas_args *args) + + start_topology_update(); + ++ /* Take down CPUs not online prior to suspend */ ++ cpuret = rtas_offline_cpus_mask(offline_mask); ++ if (cpuret) ++ pr_warn("%s: Could not restore CPUs to offline state.\n", ++ __func__); ++ ++out: ++ free_cpumask_var(offline_mask); + return atomic_read(&data.error); + } + #else /* CONFIG_PPC_PSERIES */ +diff --git a/arch/powerpc/platforms/pseries/suspend.c b/arch/powerpc/platforms/pseries/suspend.c +index 47226e0..5f997e7 100644 +--- a/arch/powerpc/platforms/pseries/suspend.c ++++ b/arch/powerpc/platforms/pseries/suspend.c +@@ -16,6 +16,7 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + ++#include + #include + #include + #include +@@ -126,11 +127,15 @@ static ssize_t store_hibernate(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) + { ++ cpumask_var_t offline_mask; + int rc; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + ++ if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY)) ++ return -ENOMEM; ++ + stream_id = simple_strtoul(buf, NULL, 16); + + do { +@@ -140,15 +145,32 @@ static ssize_t store_hibernate(struct device *dev, + } while (rc == -EAGAIN); + + if (!rc) { ++ /* All present CPUs must be online */ ++ cpumask_andnot(offline_mask, cpu_present_mask, ++ cpu_online_mask); ++ rc = rtas_online_cpus_mask(offline_mask); ++ if (rc) { ++ pr_err("%s: Could not bring present CPUs online.\n", ++ __func__); ++ goto out; ++ } ++ + stop_topology_update(); + rc = pm_suspend(PM_SUSPEND_MEM); + start_topology_update(); ++ ++ /* Take down CPUs not online prior to suspend */ ++ if (!rtas_offline_cpus_mask(offline_mask)) ++ pr_warn("%s: Could not restore CPUs to offline " ++ "state.\n", __func__); + } + + stream_id = 0; + + if (!rc) + rc = count; ++out: ++ free_cpumask_var(offline_mask); + return rc; + } + +diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c +index 4ff0ab9..90f5c0e 100644 +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -4889,6 +4889,12 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu) + if (err != EMULATE_DONE) + return 0; + ++ if (vcpu->arch.halt_request) { ++ vcpu->arch.halt_request = 0; ++ ret = kvm_emulate_halt(vcpu); ++ goto out; ++ } ++ + if (signal_pending(current)) + goto out; + if (need_resched()) +diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c +index 2992678..a7678fa 100644 +--- a/arch/x86/xen/enlighten.c ++++ b/arch/x86/xen/enlighten.c +@@ -139,6 +139,21 @@ static void xen_vcpu_setup(int cpu) + + BUG_ON(HYPERVISOR_shared_info == &xen_dummy_shared_info); + ++ /* ++ * This path is called twice on PVHVM - first during bootup via ++ * smp_init -> xen_hvm_cpu_notify, and then if the VCPU is being ++ * hotplugged: cpu_up -> xen_hvm_cpu_notify. ++ * As we can only do the VCPUOP_register_vcpu_info once lets ++ * not over-write its result. ++ * ++ * For PV it is called during restore (xen_vcpu_restore) and bootup ++ * (xen_setup_vcpu_info_placement). The hotplug mechanism does not ++ * use this function. ++ */ ++ if (xen_hvm_domain()) { ++ if (per_cpu(xen_vcpu, cpu) == &per_cpu(xen_vcpu_info, cpu)) ++ return; ++ } + if (cpu < MAX_VIRT_CPUS) + per_cpu(xen_vcpu,cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; + +diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c +index 149de45..af9f1f6 100644 +--- a/drivers/acpi/acpica/exfldio.c ++++ b/drivers/acpi/acpica/exfldio.c +@@ -722,7 +722,19 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, + + if ((obj_desc->common_field.start_field_bit_offset == 0) && + (obj_desc->common_field.bit_length == access_bit_width)) { +- status = acpi_ex_field_datum_io(obj_desc, 0, buffer, ACPI_READ); ++ if (buffer_length >= sizeof(u64)) { ++ status = ++ acpi_ex_field_datum_io(obj_desc, 0, buffer, ++ ACPI_READ); ++ } else { ++ /* Use raw_datum (u64) to handle buffers < 64 bits */ ++ ++ status = ++ acpi_ex_field_datum_io(obj_desc, 0, &raw_datum, ++ ACPI_READ); ++ ACPI_MEMCPY(buffer, &raw_datum, buffer_length); ++ } ++ + return_ACPI_STATUS(status); + } + +diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c +index a51df96..f9914e5 100644 +--- a/drivers/acpi/ec.c ++++ b/drivers/acpi/ec.c +@@ -217,7 +217,7 @@ static int ec_check_sci_sync(struct acpi_ec *ec, u8 state) + static int ec_poll(struct acpi_ec *ec) + { + unsigned long flags; +- int repeat = 2; /* number of command restarts */ ++ int repeat = 5; /* number of command restarts */ + while (repeat--) { + unsigned long delay = jiffies + + msecs_to_jiffies(ec_delay); +@@ -235,8 +235,6 @@ static int ec_poll(struct acpi_ec *ec) + } + advance_transaction(ec, acpi_ec_read_status(ec)); + } while (time_before(jiffies, delay)); +- if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) +- break; + pr_debug(PREFIX "controller reset, restart transaction\n"); + spin_lock_irqsave(&ec->curr_lock, flags); + start_transaction(ec); +diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c +index 43beaca..13cbdd3 100644 +--- a/drivers/block/drbd/drbd_receiver.c ++++ b/drivers/block/drbd/drbd_receiver.c +@@ -2225,7 +2225,6 @@ static int drbd_asb_recover_1p(struct drbd_conf *mdev) __must_hold(local) + if (hg == -1 && mdev->state.role == R_PRIMARY) { + enum drbd_state_rv rv2; + +- drbd_set_role(mdev, R_SECONDARY, 0); + /* drbd_change_state() does not sleep while in SS_IN_TRANSIENT_STATE, + * we might be here in C_WF_REPORT_PARAMS which is transient. + * we do not need to wait for the after state change work either. */ +diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c +index cdd4c09f..a22a7a5 100644 +--- a/drivers/char/ipmi/ipmi_bt_sm.c ++++ b/drivers/char/ipmi/ipmi_bt_sm.c +@@ -95,9 +95,9 @@ struct si_sm_data { + enum bt_states state; + unsigned char seq; /* BT sequence number */ + struct si_sm_io *io; +- unsigned char write_data[IPMI_MAX_MSG_LENGTH]; ++ unsigned char write_data[IPMI_MAX_MSG_LENGTH + 2]; /* +2 for memcpy */ + int write_count; +- unsigned char read_data[IPMI_MAX_MSG_LENGTH]; ++ unsigned char read_data[IPMI_MAX_MSG_LENGTH + 2]; /* +2 for memcpy */ + int read_count; + int truncated; + long timeout; /* microseconds countdown */ +diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c +index 9eb360f..d5a5f02 100644 +--- a/drivers/char/ipmi/ipmi_devintf.c ++++ b/drivers/char/ipmi/ipmi_devintf.c +@@ -837,13 +837,25 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd, + return ipmi_ioctl(filep, cmd, arg); + } + } ++ ++static long unlocked_compat_ipmi_ioctl(struct file *filep, unsigned int cmd, ++ unsigned long arg) ++{ ++ int ret; ++ ++ mutex_lock(&ipmi_mutex); ++ ret = compat_ipmi_ioctl(filep, cmd, arg); ++ mutex_unlock(&ipmi_mutex); ++ ++ return ret; ++} + #endif + + static const struct file_operations ipmi_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = ipmi_unlocked_ioctl, + #ifdef CONFIG_COMPAT +- .compat_ioctl = compat_ipmi_ioctl, ++ .compat_ioctl = unlocked_compat_ipmi_ioctl, + #endif + .open = ipmi_open, + .release = ipmi_release, +diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c +index 65c0495..d05669b 100644 +--- a/drivers/dma/pch_dma.c ++++ b/drivers/dma/pch_dma.c +@@ -476,7 +476,7 @@ static struct pch_dma_desc *pdc_desc_get(struct pch_dma_chan *pd_chan) + dev_dbg(chan2dev(&pd_chan->chan), "scanned %d descriptors\n", i); + + if (!ret) { +- ret = pdc_alloc_desc(&pd_chan->chan, GFP_NOIO); ++ ret = pdc_alloc_desc(&pd_chan->chan, GFP_ATOMIC); + if (ret) { + spin_lock(&pd_chan->lock); + pd_chan->descs_allocated++; +diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c +index 961fb54..7f88de6 100644 +--- a/drivers/gpu/drm/drm_mm.c ++++ b/drivers/gpu/drm/drm_mm.c +@@ -680,33 +680,35 @@ void drm_mm_debug_table(struct drm_mm *mm, const char *prefix) + EXPORT_SYMBOL(drm_mm_debug_table); + + #if defined(CONFIG_DEBUG_FS) +-int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm) ++static unsigned long drm_mm_dump_hole(struct seq_file *m, struct drm_mm_node *entry) + { +- struct drm_mm_node *entry; +- unsigned long total_used = 0, total_free = 0, total = 0; + unsigned long hole_start, hole_end, hole_size; + +- hole_start = drm_mm_hole_node_start(&mm->head_node); +- hole_end = drm_mm_hole_node_end(&mm->head_node); +- hole_size = hole_end - hole_start; +- if (hole_size) ++ if (entry->hole_follows) { ++ hole_start = drm_mm_hole_node_start(entry); ++ hole_end = drm_mm_hole_node_end(entry); ++ hole_size = hole_end - hole_start; + seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n", + hole_start, hole_end, hole_size); +- total_free += hole_size; ++ return hole_size; ++ } ++ ++ return 0; ++} ++ ++int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm) ++{ ++ struct drm_mm_node *entry; ++ unsigned long total_used = 0, total_free = 0, total = 0; ++ ++ total_free += drm_mm_dump_hole(m, &mm->head_node); + + drm_mm_for_each_node(entry, mm) { + seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: used\n", + entry->start, entry->start + entry->size, + entry->size); + total_used += entry->size; +- if (entry->hole_follows) { +- hole_start = drm_mm_hole_node_start(entry); +- hole_end = drm_mm_hole_node_end(entry); +- hole_size = hole_end - hole_start; +- seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n", +- hole_start, hole_end, hole_size); +- total_free += hole_size; +- } ++ total_free += drm_mm_dump_hole(m, entry); + } + total = total_free + total_used; + +diff --git a/drivers/gpu/drm/radeon/r300_cmdbuf.c b/drivers/gpu/drm/radeon/r300_cmdbuf.c +index 1fe98b4..9aa02be 100644 +--- a/drivers/gpu/drm/radeon/r300_cmdbuf.c ++++ b/drivers/gpu/drm/radeon/r300_cmdbuf.c +@@ -74,7 +74,7 @@ static int r300_emit_cliprects(drm_radeon_private_t *dev_priv, + OUT_RING(CP_PACKET0(R300_RE_CLIPRECT_TL_0, nr * 2 - 1)); + + for (i = 0; i < nr; ++i) { +- if (DRM_COPY_FROM_USER_UNCHECKED ++ if (DRM_COPY_FROM_USER + (&box, &cmdbuf->boxes[n + i], sizeof(box))) { + DRM_ERROR("copy cliprect faulted\n"); + return -EFAULT; +diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c +index 6f75887..ff62ddc 100644 +--- a/drivers/md/dm-snap.c ++++ b/drivers/md/dm-snap.c +@@ -1117,6 +1117,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) + s->pending_pool = mempool_create_slab_pool(MIN_IOS, pending_cache); + if (!s->pending_pool) { + ti->error = "Could not allocate mempool for pending exceptions"; ++ r = -ENOMEM; + goto bad_pending_pool; + } + +diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c +index 1555f0b..7c3ab8f 100644 +--- a/drivers/md/dm-thin.c ++++ b/drivers/md/dm-thin.c +@@ -2027,6 +2027,7 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) + * thin devices' discard limits consistent). + */ + ti->discards_supported = 1; ++ ti->discard_zeroes_data_unsupported = 1; + } + ti->private = pt; + +@@ -2443,7 +2444,6 @@ static void set_discard_limits(struct pool *pool, struct queue_limits *limits) + * bios that overlap 2 blocks. + */ + limits->discard_granularity = pool->sectors_per_block << SECTOR_SHIFT; +- limits->discard_zeroes_data = pool->pf.zero_new_blocks; + } + + static void pool_io_hints(struct dm_target *ti, struct queue_limits *limits) +diff --git a/drivers/net/ethernet/3com/3c509.c b/drivers/net/ethernet/3com/3c509.c +index 41719da..9040a62 100644 +--- a/drivers/net/ethernet/3com/3c509.c ++++ b/drivers/net/ethernet/3com/3c509.c +@@ -309,6 +309,7 @@ static int __devinit el3_isa_match(struct device *pdev, + if (!dev) + return -ENOMEM; + ++ SET_NETDEV_DEV(dev, pdev); + netdev_boot_setup_check(dev); + + if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509-isa")) { +@@ -704,6 +705,7 @@ static int __init el3_eisa_probe (struct device *device) + return -ENOMEM; + } + ++ SET_NETDEV_DEV(dev, device); + netdev_boot_setup_check(dev); + + el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_EISA); +diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c +index e463d10..5673d6e 100644 +--- a/drivers/net/ethernet/3com/3c59x.c ++++ b/drivers/net/ethernet/3com/3c59x.c +@@ -632,7 +632,6 @@ struct vortex_private { + pm_state_valid:1, /* pci_dev->saved_config_space has sane contents */ + open:1, + medialock:1, +- must_free_region:1, /* Flag: if zero, Cardbus owns the I/O region */ + large_frames:1, /* accept large frames */ + handling_irq:1; /* private in_irq indicator */ + /* {get|set}_wol operations are already serialized by rtnl. +@@ -951,7 +950,7 @@ static int __devexit vortex_eisa_remove(struct device *device) + + unregister_netdev(dev); + iowrite16(TotalReset|0x14, ioaddr + EL3_CMD); +- release_region(dev->base_addr, VORTEX_TOTAL_SIZE); ++ release_region(edev->base_addr, VORTEX_TOTAL_SIZE); + + free_netdev(dev); + return 0; +@@ -1012,6 +1011,12 @@ static int __devinit vortex_init_one(struct pci_dev *pdev, + if (rc < 0) + goto out; + ++ rc = pci_request_regions(pdev, DRV_NAME); ++ if (rc < 0) { ++ pci_disable_device(pdev); ++ goto out; ++ } ++ + unit = vortex_cards_found; + + if (global_use_mmio < 0 && (unit >= MAX_UNITS || use_mmio[unit] < 0)) { +@@ -1027,6 +1032,7 @@ static int __devinit vortex_init_one(struct pci_dev *pdev, + if (!ioaddr) /* If mapping fails, fall-back to BAR 0... */ + ioaddr = pci_iomap(pdev, 0, 0); + if (!ioaddr) { ++ pci_release_regions(pdev); + pci_disable_device(pdev); + rc = -ENOMEM; + goto out; +@@ -1036,6 +1042,7 @@ static int __devinit vortex_init_one(struct pci_dev *pdev, + ent->driver_data, unit); + if (rc < 0) { + pci_iounmap(pdev, ioaddr); ++ pci_release_regions(pdev); + pci_disable_device(pdev); + goto out; + } +@@ -1179,11 +1186,6 @@ static int __devinit vortex_probe1(struct device *gendev, + + /* PCI-only startup logic */ + if (pdev) { +- /* EISA resources already marked, so only PCI needs to do this here */ +- /* Ignore return value, because Cardbus drivers already allocate for us */ +- if (request_region(dev->base_addr, vci->io_size, print_name) != NULL) +- vp->must_free_region = 1; +- + /* enable bus-mastering if necessary */ + if (vci->flags & PCI_USES_MASTER) + pci_set_master(pdev); +@@ -1221,7 +1223,7 @@ static int __devinit vortex_probe1(struct device *gendev, + &vp->rx_ring_dma); + retval = -ENOMEM; + if (!vp->rx_ring) +- goto free_region; ++ goto free_device; + + vp->tx_ring = (struct boom_tx_desc *)(vp->rx_ring + RX_RING_SIZE); + vp->tx_ring_dma = vp->rx_ring_dma + sizeof(struct boom_rx_desc) * RX_RING_SIZE; +@@ -1486,9 +1488,7 @@ free_ring: + + sizeof(struct boom_tx_desc) * TX_RING_SIZE, + vp->rx_ring, + vp->rx_ring_dma); +-free_region: +- if (vp->must_free_region) +- release_region(dev->base_addr, vci->io_size); ++free_device: + free_netdev(dev); + pr_err(PFX "vortex_probe1 fails. Returns %d\n", retval); + out: +@@ -3256,8 +3256,9 @@ static void __devexit vortex_remove_one(struct pci_dev *pdev) + + sizeof(struct boom_tx_desc) * TX_RING_SIZE, + vp->rx_ring, + vp->rx_ring_dma); +- if (vp->must_free_region) +- release_region(dev->base_addr, vp->io_size); ++ ++ pci_release_regions(pdev); ++ + free_netdev(dev); + } + +diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c +index dd037dd..cf20388 100644 +--- a/drivers/net/ethernet/realtek/r8169.c ++++ b/drivers/net/ethernet/realtek/r8169.c +@@ -1690,8 +1690,6 @@ static void rtl8169_rx_vlan_tag(struct RxDesc *desc, struct sk_buff *skb) + + if (opts2 & RxVlanTag) + __vlan_hwaccel_put_tag(skb, swab16(opts2 & 0xffff)); +- +- desc->opts2 = 0; + } + + static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd) +@@ -5434,8 +5432,6 @@ static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, u32 budget + !(status & (RxRWT | RxFOVF)) && + (dev->features & NETIF_F_RXALL)) + goto process_pkt; +- +- rtl8169_mark_to_asic(desc, rx_buf_sz); + } else { + struct sk_buff *skb; + dma_addr_t addr; +@@ -5456,16 +5452,14 @@ process_pkt: + if (unlikely(rtl8169_fragmented_frame(status))) { + dev->stats.rx_dropped++; + dev->stats.rx_length_errors++; +- rtl8169_mark_to_asic(desc, rx_buf_sz); +- continue; ++ goto release_descriptor; + } + + skb = rtl8169_try_rx_copy(tp->Rx_databuff[entry], + tp, pkt_size, addr); +- rtl8169_mark_to_asic(desc, rx_buf_sz); + if (!skb) { + dev->stats.rx_dropped++; +- continue; ++ goto release_descriptor; + } + + rtl8169_rx_csum(skb, status); +@@ -5481,6 +5475,10 @@ process_pkt: + tp->rx_stats.bytes += pkt_size; + u64_stats_update_end(&tp->rx_stats.syncp); + } ++release_descriptor: ++ desc->opts2 = 0; ++ wmb(); ++ rtl8169_mark_to_asic(desc, rx_buf_sz); + } + + count = cur_rx - tp->cur_rx; +diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c +index eb85217..192026f 100644 +--- a/drivers/net/ethernet/sfc/mcdi.c ++++ b/drivers/net/ethernet/sfc/mcdi.c +@@ -640,7 +640,7 @@ fail: + int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address, + u16 *fw_subtype_list, u32 *capabilities) + { +- uint8_t outbuf[MC_CMD_GET_BOARD_CFG_OUT_LENMIN]; ++ uint8_t outbuf[MC_CMD_GET_BOARD_CFG_OUT_LENMAX]; + size_t outlen, offset, i; + int port_num = efx_port_num(efx); + int rc; +diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c +index 956a5ed..7160523 100644 +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -205,7 +205,8 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb) + } + + if (port->passthru) +- vlan = list_first_entry(&port->vlans, struct macvlan_dev, list); ++ vlan = list_first_or_null_rcu(&port->vlans, ++ struct macvlan_dev, list); + else + vlan = macvlan_hash_lookup(port, eth->h_dest); + if (vlan == NULL) +@@ -724,7 +725,7 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, + if (err < 0) + goto destroy_port; + +- list_add_tail(&vlan->list, &port->vlans); ++ list_add_tail_rcu(&vlan->list, &port->vlans); + netif_stacked_transfer_operstate(lowerdev, dev); + + return 0; +@@ -750,7 +751,7 @@ void macvlan_dellink(struct net_device *dev, struct list_head *head) + { + struct macvlan_dev *vlan = netdev_priv(dev); + +- list_del(&vlan->list); ++ list_del_rcu(&vlan->list); + unregister_netdevice_queue(dev, head); + } + EXPORT_SYMBOL_GPL(macvlan_dellink); +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index 8669c77..3b6e932 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -174,6 +175,93 @@ err: + return status; + } + ++/* default ethernet address used by the modem */ ++static const u8 default_modem_addr[ETH_ALEN] = {0x02, 0x50, 0xf3}; ++ ++/* Make up an ethernet header if the packet doesn't have one. ++ * ++ * A firmware bug common among several devices cause them to send raw ++ * IP packets under some circumstances. There is no way for the ++ * driver/host to know when this will happen. And even when the bug ++ * hits, some packets will still arrive with an intact header. ++ * ++ * The supported devices are only capably of sending IPv4, IPv6 and ++ * ARP packets on a point-to-point link. Any packet with an ethernet ++ * header will have either our address or a broadcast/multicast ++ * address as destination. ARP packets will always have a header. ++ * ++ * This means that this function will reliably add the appropriate ++ * header iff necessary, provided our hardware address does not start ++ * with 4 or 6. ++ * ++ * Another common firmware bug results in all packets being addressed ++ * to 00:a0:c6:00:00:00 despite the host address being different. ++ * This function will also fixup such packets. ++ */ ++static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ++{ ++ __be16 proto; ++ ++ /* usbnet rx_complete guarantees that skb->len is at least ++ * hard_header_len, so we can inspect the dest address without ++ * checking skb->len ++ */ ++ switch (skb->data[0] & 0xf0) { ++ case 0x40: ++ proto = htons(ETH_P_IP); ++ break; ++ case 0x60: ++ proto = htons(ETH_P_IPV6); ++ break; ++ case 0x00: ++ if (is_multicast_ether_addr(skb->data)) ++ return 1; ++ /* possibly bogus destination - rewrite just in case */ ++ skb_reset_mac_header(skb); ++ goto fix_dest; ++ default: ++ /* pass along other packets without modifications */ ++ return 1; ++ } ++ if (skb_headroom(skb) < ETH_HLEN) ++ return 0; ++ skb_push(skb, ETH_HLEN); ++ skb_reset_mac_header(skb); ++ eth_hdr(skb)->h_proto = proto; ++ memset(eth_hdr(skb)->h_source, 0, ETH_ALEN); ++fix_dest: ++ memcpy(eth_hdr(skb)->h_dest, dev->net->dev_addr, ETH_ALEN); ++ return 1; ++} ++ ++/* very simplistic detection of IPv4 or IPv6 headers */ ++static bool possibly_iphdr(const char *data) ++{ ++ return (data[0] & 0xd0) == 0x40; ++} ++ ++/* disallow addresses which may be confused with IP headers */ ++static int qmi_wwan_mac_addr(struct net_device *dev, void *p) ++{ ++ struct sockaddr *addr = p; ++ ++ if (!is_valid_ether_addr(addr->sa_data) || ++ possibly_iphdr(addr->sa_data)) ++ return -EADDRNOTAVAIL; ++ memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); ++ return 0; ++} ++ ++static const struct net_device_ops qmi_wwan_netdev_ops = { ++ .ndo_open = usbnet_open, ++ .ndo_stop = usbnet_stop, ++ .ndo_start_xmit = usbnet_start_xmit, ++ .ndo_tx_timeout = usbnet_tx_timeout, ++ .ndo_change_mtu = usbnet_change_mtu, ++ .ndo_set_mac_address = qmi_wwan_mac_addr, ++ .ndo_validate_addr = eth_validate_addr, ++}; ++ + /* using a counter to merge subdriver requests with our own into a combined state */ + static int qmi_wwan_manage_power(struct usbnet *dev, int on) + { +@@ -257,6 +345,18 @@ static int qmi_wwan_bind_shared(struct usbnet *dev, struct usb_interface *intf) + /* save subdriver struct for suspend/resume wrappers */ + dev->data[0] = (unsigned long)subdriver; + ++ /* Never use the same address on both ends of the link, even ++ * if the buggy firmware told us to. ++ */ ++ if (!compare_ether_addr(dev->net->dev_addr, default_modem_addr)) ++ eth_hw_addr_random(dev->net); ++ ++ /* make MAC addr easily distinguishable from an IP header */ ++ if (possibly_iphdr(dev->net->dev_addr)) { ++ dev->net->dev_addr[0] |= 0x02; /* set local assignment bit */ ++ dev->net->dev_addr[0] &= 0xbf; /* clear "IP" bit */ ++ } ++ dev->net->netdev_ops = &qmi_wwan_netdev_ops; + err: + return rv; + } +@@ -326,6 +426,7 @@ static const struct driver_info qmi_wwan_shared = { + .bind = qmi_wwan_bind_shared, + .unbind = qmi_wwan_unbind_shared, + .manage_power = qmi_wwan_manage_power, ++ .rx_fixup = qmi_wwan_rx_fixup, + }; + + static const struct driver_info qmi_wwan_force_int0 = { +diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c +index 91e2c4f..f6a095f 100644 +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -1711,6 +1711,7 @@ static int ath9k_sta_add(struct ieee80211_hw *hw, + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_node *an = (struct ath_node *) sta->drv_priv; + struct ieee80211_key_conf ps_key = { }; ++ int key; + + ath_node_attach(sc, sta, vif); + +@@ -1718,7 +1719,9 @@ static int ath9k_sta_add(struct ieee80211_hw *hw, + vif->type != NL80211_IFTYPE_AP_VLAN) + return 0; + +- an->ps_key = ath_key_config(common, vif, sta, &ps_key); ++ key = ath_key_config(common, vif, sta, &ps_key); ++ if (key > 0) ++ an->ps_key = key; + + return 0; + } +@@ -1735,6 +1738,7 @@ static void ath9k_del_ps_key(struct ath_softc *sc, + return; + + ath_key_delete(common, &ps_key); ++ an->ps_key = 0; + } + + static int ath9k_sta_remove(struct ieee80211_hw *hw, +diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c +index bb2848a..448f545 100644 +--- a/drivers/net/wireless/b43/dma.c ++++ b/drivers/net/wireless/b43/dma.c +@@ -1733,6 +1733,25 @@ drop_recycle_buffer: + sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize); + } + ++void b43_dma_handle_rx_overflow(struct b43_dmaring *ring) ++{ ++ int current_slot, previous_slot; ++ ++ B43_WARN_ON(ring->tx); ++ ++ /* Device has filled all buffers, drop all packets and let TCP ++ * decrease speed. ++ * Decrement RX index by one will let the device to see all slots ++ * as free again ++ */ ++ /* ++ *TODO: How to increase rx_drop in mac80211? ++ */ ++ current_slot = ring->ops->get_current_rxslot(ring); ++ previous_slot = prev_slot(ring, current_slot); ++ ring->ops->set_current_rxslot(ring, previous_slot); ++} ++ + void b43_dma_rx(struct b43_dmaring *ring) + { + const struct b43_dma_ops *ops = ring->ops; +diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h +index 9fdd198..df8c8cd 100644 +--- a/drivers/net/wireless/b43/dma.h ++++ b/drivers/net/wireless/b43/dma.h +@@ -9,7 +9,7 @@ + /* DMA-Interrupt reasons. */ + #define B43_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \ + | (1 << 14) | (1 << 15)) +-#define B43_DMAIRQ_NONFATALMASK (1 << 13) ++#define B43_DMAIRQ_RDESC_UFLOW (1 << 13) + #define B43_DMAIRQ_RX_DONE (1 << 16) + + /*** 32-bit DMA Engine. ***/ +@@ -295,6 +295,8 @@ int b43_dma_tx(struct b43_wldev *dev, + void b43_dma_handle_txstatus(struct b43_wldev *dev, + const struct b43_txstatus *status); + ++void b43_dma_handle_rx_overflow(struct b43_dmaring *ring); ++ + void b43_dma_rx(struct b43_dmaring *ring); + + void b43_dma_direct_fifo_rx(struct b43_wldev *dev, +diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c +index 14fd2ca..b54c750 100644 +--- a/drivers/net/wireless/b43/main.c ++++ b/drivers/net/wireless/b43/main.c +@@ -1895,30 +1895,18 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev) + } + } + +- if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK | +- B43_DMAIRQ_NONFATALMASK))) { +- if (merged_dma_reason & B43_DMAIRQ_FATALMASK) { +- b43err(dev->wl, "Fatal DMA error: " +- "0x%08X, 0x%08X, 0x%08X, " +- "0x%08X, 0x%08X, 0x%08X\n", +- dma_reason[0], dma_reason[1], +- dma_reason[2], dma_reason[3], +- dma_reason[4], dma_reason[5]); +- b43err(dev->wl, "This device does not support DMA " ++ if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK))) { ++ b43err(dev->wl, ++ "Fatal DMA error: 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X\n", ++ dma_reason[0], dma_reason[1], ++ dma_reason[2], dma_reason[3], ++ dma_reason[4], dma_reason[5]); ++ b43err(dev->wl, "This device does not support DMA " + "on your system. It will now be switched to PIO.\n"); +- /* Fall back to PIO transfers if we get fatal DMA errors! */ +- dev->use_pio = true; +- b43_controller_restart(dev, "DMA error"); +- return; +- } +- if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) { +- b43err(dev->wl, "DMA error: " +- "0x%08X, 0x%08X, 0x%08X, " +- "0x%08X, 0x%08X, 0x%08X\n", +- dma_reason[0], dma_reason[1], +- dma_reason[2], dma_reason[3], +- dma_reason[4], dma_reason[5]); +- } ++ /* Fall back to PIO transfers if we get fatal DMA errors! */ ++ dev->use_pio = true; ++ b43_controller_restart(dev, "DMA error"); ++ return; + } + + if (unlikely(reason & B43_IRQ_UCODE_DEBUG)) +@@ -1937,6 +1925,11 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev) + handle_irq_noise(dev); + + /* Check the DMA reason registers for received data. */ ++ if (dma_reason[0] & B43_DMAIRQ_RDESC_UFLOW) { ++ if (B43_DEBUG) ++ b43warn(dev->wl, "RX descriptor underrun\n"); ++ b43_dma_handle_rx_overflow(dev->dma.rx_ring); ++ } + if (dma_reason[0] & B43_DMAIRQ_RX_DONE) { + if (b43_using_pio_transfers(dev)) + b43_pio_rx(dev->pio.rx_queue); +@@ -1994,7 +1987,7 @@ static irqreturn_t b43_do_interrupt(struct b43_wldev *dev) + return IRQ_NONE; + + dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON) +- & 0x0001DC00; ++ & 0x0001FC00; + dev->dma_reason[1] = b43_read32(dev, B43_MMIO_DMA1_REASON) + & 0x0000DC00; + dev->dma_reason[2] = b43_read32(dev, B43_MMIO_DMA2_REASON) +@@ -3122,7 +3115,7 @@ static int b43_chip_init(struct b43_wldev *dev) + b43_write32(dev, 0x018C, 0x02000000); + } + b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, 0x00004000); +- b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001DC00); ++ b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001FC00); + b43_write32(dev, B43_MMIO_DMA1_IRQ_MASK, 0x0000DC00); + b43_write32(dev, B43_MMIO_DMA2_IRQ_MASK, 0x0000DC00); + b43_write32(dev, B43_MMIO_DMA3_IRQ_MASK, 0x0001DC00); +diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c +index 2977a12..3050b6a 100644 +--- a/drivers/net/wireless/mwifiex/cmdevt.c ++++ b/drivers/net/wireless/mwifiex/cmdevt.c +@@ -1084,6 +1084,7 @@ mwifiex_process_hs_config(struct mwifiex_adapter *adapter) + adapter->if_ops.wakeup(adapter); + adapter->hs_activated = false; + adapter->is_hs_configured = false; ++ adapter->is_suspended = false; + mwifiex_hs_activated_event(mwifiex_get_priv(adapter, + MWIFIEX_BSS_ROLE_ANY), + false); +diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c +index 4fb146a..dc70c0f 100644 +--- a/drivers/net/wireless/mwifiex/sta_ioctl.c ++++ b/drivers/net/wireless/mwifiex/sta_ioctl.c +@@ -105,7 +105,7 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv, + } else { + /* Multicast */ + priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_PROMISCUOUS_ENABLE; +- if (mcast_list->mode == MWIFIEX_MULTICAST_MODE) { ++ if (mcast_list->mode == MWIFIEX_ALL_MULTI_MODE) { + dev_dbg(priv->adapter->dev, + "info: Enabling All Multicast!\n"); + priv->curr_pkt_filter |= +@@ -117,20 +117,11 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv, + dev_dbg(priv->adapter->dev, + "info: Set multicast list=%d\n", + mcast_list->num_multicast_addr); +- /* Set multicast addresses to firmware */ +- if (old_pkt_filter == priv->curr_pkt_filter) { +- /* Send request to firmware */ +- ret = mwifiex_send_cmd_async(priv, +- HostCmd_CMD_MAC_MULTICAST_ADR, +- HostCmd_ACT_GEN_SET, 0, +- mcast_list); +- } else { +- /* Send request to firmware */ +- ret = mwifiex_send_cmd_async(priv, +- HostCmd_CMD_MAC_MULTICAST_ADR, +- HostCmd_ACT_GEN_SET, 0, +- mcast_list); +- } ++ /* Send multicast addresses to firmware */ ++ ret = mwifiex_send_cmd_async(priv, ++ HostCmd_CMD_MAC_MULTICAST_ADR, ++ HostCmd_ACT_GEN_SET, 0, ++ mcast_list); + } + } + } +diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c +index 22b2dfa..fdacfce 100644 +--- a/drivers/platform/x86/hp_accel.c ++++ b/drivers/platform/x86/hp_accel.c +@@ -362,7 +362,8 @@ static int lis3lv02d_suspend(struct acpi_device *device, pm_message_t state) + + static int lis3lv02d_resume(struct acpi_device *device) + { +- return lis3lv02d_poweron(&lis3_dev); ++ lis3lv02d_poweron(&lis3_dev); ++ return 0; + } + #else + #define lis3lv02d_suspend NULL +diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c +index 8361187..9ea2555 100644 +--- a/drivers/rtc/rtc-pcf2123.c ++++ b/drivers/rtc/rtc-pcf2123.c +@@ -264,6 +264,7 @@ static int __devinit pcf2123_probe(struct spi_device *spi) + + if (!(rxbuf[0] & 0x20)) { + dev_err(&spi->dev, "chip not found\n"); ++ ret = -ENODEV; + goto kfree_exit; + } + +diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c +index 5b3cadb..2bbb845 100644 +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -140,6 +140,7 @@ sd_store_cache_type(struct device *dev, struct device_attribute *attr, + char *buffer_data; + struct scsi_mode_data data; + struct scsi_sense_hdr sshdr; ++ const char *temp = "temporary "; + int len; + + if (sdp->type != TYPE_DISK) +@@ -148,6 +149,13 @@ sd_store_cache_type(struct device *dev, struct device_attribute *attr, + * it's not worth the risk */ + return -EINVAL; + ++ if (strncmp(buf, temp, sizeof(temp) - 1) == 0) { ++ buf += sizeof(temp) - 1; ++ sdkp->cache_override = 1; ++ } else { ++ sdkp->cache_override = 0; ++ } ++ + for (i = 0; i < ARRAY_SIZE(sd_cache_types); i++) { + len = strlen(sd_cache_types[i]); + if (strncmp(sd_cache_types[i], buf, len) == 0 && +@@ -160,6 +168,13 @@ sd_store_cache_type(struct device *dev, struct device_attribute *attr, + return -EINVAL; + rcd = ct & 0x01 ? 1 : 0; + wce = ct & 0x02 ? 1 : 0; ++ ++ if (sdkp->cache_override) { ++ sdkp->WCE = wce; ++ sdkp->RCD = rcd; ++ return count; ++ } ++ + if (scsi_mode_sense(sdp, 0x08, 8, buffer, sizeof(buffer), SD_TIMEOUT, + SD_MAX_RETRIES, &data, NULL)) + return -EINVAL; +@@ -2126,6 +2141,10 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) + int old_rcd = sdkp->RCD; + int old_dpofua = sdkp->DPOFUA; + ++ ++ if (sdkp->cache_override) ++ return; ++ + first_len = 4; + if (sdp->skip_ms_page_8) { + if (sdp->type == TYPE_RBC) +@@ -2607,6 +2626,7 @@ static void sd_probe_async(void *data, async_cookie_t cookie) + sdkp->capacity = 0; + sdkp->media_present = 1; + sdkp->write_prot = 0; ++ sdkp->cache_override = 0; + sdkp->WCE = 0; + sdkp->RCD = 0; + sdkp->ATO = 0; +diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h +index f703f48..e2b2956 100644 +--- a/drivers/scsi/sd.h ++++ b/drivers/scsi/sd.h +@@ -67,6 +67,7 @@ struct scsi_disk { + u8 protection_type;/* Data Integrity Field */ + u8 provisioning_mode; + unsigned ATO : 1; /* state of disk ATO bit */ ++ unsigned cache_override : 1; /* temp override of WCE,RCD */ + unsigned WCE : 1; /* state of disk WCE bit */ + unsigned RCD : 1; /* state of disk RCD bit, unused */ + unsigned DPOFUA : 1; /* state of disk DPOFUA bit */ +diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c +index 006f605..fd669b5 100644 +--- a/drivers/target/iscsi/iscsi_target_erl1.c ++++ b/drivers/target/iscsi/iscsi_target_erl1.c +@@ -824,7 +824,7 @@ static int iscsit_attach_ooo_cmdsn( + /* + * CmdSN is greater than the tail of the list. + */ +- if (ooo_tail->cmdsn < ooo_cmdsn->cmdsn) ++ if (iscsi_sna_lt(ooo_tail->cmdsn, ooo_cmdsn->cmdsn)) + list_add_tail(&ooo_cmdsn->ooo_list, + &sess->sess_ooo_cmdsn_list); + else { +@@ -834,11 +834,12 @@ static int iscsit_attach_ooo_cmdsn( + */ + list_for_each_entry(ooo_tmp, &sess->sess_ooo_cmdsn_list, + ooo_list) { +- if (ooo_tmp->cmdsn < ooo_cmdsn->cmdsn) ++ if (iscsi_sna_lt(ooo_tmp->cmdsn, ooo_cmdsn->cmdsn)) + continue; + ++ /* Insert before this entry */ + list_add(&ooo_cmdsn->ooo_list, +- &ooo_tmp->ooo_list); ++ ooo_tmp->ooo_list.prev); + break; + } + } +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index ec970cb..19e4518 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -1980,7 +1980,11 @@ repeat: + group = ac->ac_g_ex.fe_group; + + for (i = 0; i < ngroups; group++, i++) { +- if (group == ngroups) ++ /* ++ * Artificially restricted ngroups for non-extent ++ * files makes group > ngroups possible on first loop. ++ */ ++ if (group >= ngroups) + group = 0; + + /* This now checks without needing the buddy page */ +diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c +index 001ef01..36ad5b4 100644 +--- a/fs/hugetlbfs/inode.c ++++ b/fs/hugetlbfs/inode.c +@@ -927,9 +927,13 @@ static int can_do_hugetlb_shm(void) + return capable(CAP_IPC_LOCK) || in_group_p(sysctl_hugetlb_shm_group); + } + +-struct file *hugetlb_file_setup(const char *name, unsigned long addr, +- size_t size, vm_flags_t acctflag, +- struct user_struct **user, int creat_flags) ++/* ++ * Note that size should be aligned to proper hugepage size in caller side, ++ * otherwise hugetlb_reserve_pages reserves one less hugepages than intended. ++ */ ++struct file *hugetlb_file_setup(const char *name, size_t size, ++ vm_flags_t acctflag, struct user_struct **user, ++ int creat_flags) + { + int error = -ENOMEM; + struct file *file; +@@ -937,8 +941,6 @@ struct file *hugetlb_file_setup(const char *name, unsigned long addr, + struct path path; + struct dentry *root; + struct qstr quick_string; +- struct hstate *hstate; +- unsigned long num_pages; + + *user = NULL; + if (!hugetlbfs_vfsmount) +@@ -972,12 +974,10 @@ struct file *hugetlb_file_setup(const char *name, unsigned long addr, + if (!inode) + goto out_dentry; + +- hstate = hstate_inode(inode); +- size += addr & ~huge_page_mask(hstate); +- num_pages = ALIGN(size, huge_page_size(hstate)) >> +- huge_page_shift(hstate); + error = -ENOMEM; +- if (hugetlb_reserve_pages(inode, 0, num_pages, NULL, acctflag)) ++ if (hugetlb_reserve_pages(inode, 0, ++ size >> huge_page_shift(hstate_inode(inode)), NULL, ++ acctflag)) + goto out_inode; + + d_instantiate(path.dentry, inode); +diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c +index dd0308d..64198ed 100644 +--- a/fs/nfsd/nfs4proc.c ++++ b/fs/nfsd/nfs4proc.c +@@ -270,6 +270,7 @@ static __be32 + do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) + { + __be32 status; ++ int accmode = 0; + + /* We don't know the target directory, and therefore can not + * set the change info +@@ -283,9 +284,19 @@ do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_ + + open->op_truncate = (open->op_iattr.ia_valid & ATTR_SIZE) && + (open->op_iattr.ia_size == 0); ++ /* ++ * In the delegation case, the client is telling us about an ++ * open that it *already* performed locally, some time ago. We ++ * should let it succeed now if possible. ++ * ++ * In the case of a CLAIM_FH open, on the other hand, the client ++ * may be counting on us to enforce permissions (the Linux 4.1 ++ * client uses this for normal opens, for example). ++ */ ++ if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEG_CUR_FH) ++ accmode = NFSD_MAY_OWNER_OVERRIDE; + +- status = do_open_permission(rqstp, current_fh, open, +- NFSD_MAY_OWNER_OVERRIDE); ++ status = do_open_permission(rqstp, current_fh, open, accmode); + + return status; + } +diff --git a/include/linux/audit.h b/include/linux/audit.h +index ed3ef19..4f334d5 100644 +--- a/include/linux/audit.h ++++ b/include/linux/audit.h +@@ -480,7 +480,7 @@ static inline void audit_syscall_entry(int arch, int major, unsigned long a0, + unsigned long a1, unsigned long a2, + unsigned long a3) + { +- if (unlikely(!audit_dummy_context())) ++ if (unlikely(current->audit_context)) + __audit_syscall_entry(arch, major, a0, a1, a2, a3); + } + static inline void audit_syscall_exit(void *pt_regs) +diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h +index 000837e..2c36a71 100644 +--- a/include/linux/hugetlb.h ++++ b/include/linux/hugetlb.h +@@ -152,8 +152,7 @@ static inline struct hugetlbfs_sb_info *HUGETLBFS_SB(struct super_block *sb) + + extern const struct file_operations hugetlbfs_file_operations; + extern const struct vm_operations_struct hugetlb_vm_ops; +-struct file *hugetlb_file_setup(const char *name, unsigned long addr, +- size_t size, vm_flags_t acct, ++struct file *hugetlb_file_setup(const char *name, size_t size, vm_flags_t acct, + struct user_struct **user, int creat_flags); + + static inline int is_file_hugepages(struct file *file) +@@ -170,8 +169,8 @@ static inline int is_file_hugepages(struct file *file) + + #define is_file_hugepages(file) 0 + static inline struct file * +-hugetlb_file_setup(const char *name, unsigned long addr, size_t size, +- vm_flags_t acctflag, struct user_struct **user, int creat_flags) ++hugetlb_file_setup(const char *name, size_t size, vm_flags_t acctflag, ++ struct user_struct **user, int creat_flags) + { + return ERR_PTR(-ENOSYS); + } +@@ -294,7 +293,7 @@ static inline unsigned hstate_index_to_shift(unsigned index) + return hstates[index].order + PAGE_SHIFT; + } + +-#else ++#else /* CONFIG_HUGETLB_PAGE */ + struct hstate {}; + #define alloc_huge_page_node(h, nid) NULL + #define alloc_bootmem_huge_page(h) NULL +diff --git a/include/linux/if_cablemodem.h b/include/linux/if_cablemodem.h +index 9ca1007..ee6b3c4 100644 +--- a/include/linux/if_cablemodem.h ++++ b/include/linux/if_cablemodem.h +@@ -12,11 +12,11 @@ + */ + + /* some useful defines for sb1000.c e cmconfig.c - fv */ +-#define SIOCGCMSTATS SIOCDEVPRIVATE+0 /* get cable modem stats */ +-#define SIOCGCMFIRMWARE SIOCDEVPRIVATE+1 /* get cm firmware version */ +-#define SIOCGCMFREQUENCY SIOCDEVPRIVATE+2 /* get cable modem frequency */ +-#define SIOCSCMFREQUENCY SIOCDEVPRIVATE+3 /* set cable modem frequency */ +-#define SIOCGCMPIDS SIOCDEVPRIVATE+4 /* get cable modem PIDs */ +-#define SIOCSCMPIDS SIOCDEVPRIVATE+5 /* set cable modem PIDs */ ++#define SIOCGCMSTATS (SIOCDEVPRIVATE+0) /* get cable modem stats */ ++#define SIOCGCMFIRMWARE (SIOCDEVPRIVATE+1) /* get cm firmware version */ ++#define SIOCGCMFREQUENCY (SIOCDEVPRIVATE+2) /* get cable modem frequency */ ++#define SIOCSCMFREQUENCY (SIOCDEVPRIVATE+3) /* set cable modem frequency */ ++#define SIOCGCMPIDS (SIOCDEVPRIVATE+4) /* get cable modem PIDs */ ++#define SIOCSCMPIDS (SIOCDEVPRIVATE+5) /* set cable modem PIDs */ + + #endif +diff --git a/include/linux/rculist.h b/include/linux/rculist.h +index d079290..6f95e24 100644 +--- a/include/linux/rculist.h ++++ b/include/linux/rculist.h +@@ -242,6 +242,23 @@ static inline void list_splice_init_rcu(struct list_head *list, + list_entry_rcu((ptr)->next, type, member) + + /** ++ * list_first_or_null_rcu - get the first element from a list ++ * @ptr: the list head to take the element from. ++ * @type: the type of the struct this is embedded in. ++ * @member: the name of the list_struct within the struct. ++ * ++ * Note that if the list is empty, it returns NULL. ++ * ++ * This primitive may safely run concurrently with the _rcu list-mutation ++ * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock(). ++ */ ++#define list_first_or_null_rcu(ptr, type, member) \ ++ ({struct list_head *__ptr = (ptr); \ ++ struct list_head __rcu *__next = list_next_rcu(__ptr); \ ++ likely(__ptr != __next) ? container_of(__next, type, member) : NULL; \ ++ }) ++ ++/** + * list_for_each_entry_rcu - iterate over rcu list of given type + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. +diff --git a/include/net/sock.h b/include/net/sock.h +index 59a8947..f673ba5 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -793,6 +793,18 @@ struct inet_hashinfo; + struct raw_hashinfo; + struct module; + ++/* ++ * caches using SLAB_DESTROY_BY_RCU should let .next pointer from nulls nodes ++ * un-modified. Special care is taken when initializing object to zero. ++ */ ++static inline void sk_prot_clear_nulls(struct sock *sk, int size) ++{ ++ if (offsetof(struct sock, sk_node.next) != 0) ++ memset(sk, 0, offsetof(struct sock, sk_node.next)); ++ memset(&sk->sk_node.pprev, 0, ++ size - offsetof(struct sock, sk_node.pprev)); ++} ++ + /* Networking protocol blocks we attach to sockets. + * socket layer -> transport layer interface + * transport -> network interface is defined by struct inet_proto +diff --git a/include/net/tcp.h b/include/net/tcp.h +index 2757a11..8376a6a 100644 +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -948,6 +948,7 @@ static inline int tcp_prequeue(struct sock *sk, struct sk_buff *skb) + if (sysctl_tcp_low_latency || !tp->ucopy.task) + return 0; + ++ skb_dst_force(skb); + __skb_queue_tail(&tp->ucopy.prequeue, skb); + tp->ucopy.memory += skb->truesize; + if (tp->ucopy.memory > sk->sk_rcvbuf) { +diff --git a/ipc/shm.c b/ipc/shm.c +index 85d81b4..a02ef57 100644 +--- a/ipc/shm.c ++++ b/ipc/shm.c +@@ -479,10 +479,12 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) + + sprintf (name, "SYSV%08x", key); + if (shmflg & SHM_HUGETLB) { ++ size_t hugesize = ALIGN(size, huge_page_size(&default_hstate)); ++ + /* hugetlb_file_setup applies strict accounting */ + if (shmflg & SHM_NORESERVE) + acctflag = VM_NORESERVE; +- file = hugetlb_file_setup(name, 0, size, acctflag, ++ file = hugetlb_file_setup(name, hugesize, acctflag, + &shp->mlock_user, HUGETLB_SHMFS_INODE); + } else { + /* +diff --git a/kernel/kmod.c b/kernel/kmod.c +index 05698a7..f2490e1 100644 +--- a/kernel/kmod.c ++++ b/kernel/kmod.c +@@ -541,6 +541,11 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait) + int retval = 0; + + helper_lock(); ++ if (!sub_info->path) { ++ retval = -EINVAL; ++ goto out; ++ } ++ + if (sub_info->path[0] == '\0') + goto out; + +diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c +index 01d8e62..6570548 100644 +--- a/kernel/time/tick-sched.c ++++ b/kernel/time/tick-sched.c +@@ -866,7 +866,7 @@ void tick_cancel_sched_timer(int cpu) + hrtimer_cancel(&ts->sched_timer); + # endif + +- ts->nohz_mode = NOHZ_MODE_INACTIVE; ++ memset(ts, 0, sizeof(*ts)); + } + #endif + +diff --git a/kernel/timer.c b/kernel/timer.c +index 6dfdb72..dd93d90 100644 +--- a/kernel/timer.c ++++ b/kernel/timer.c +@@ -1680,12 +1680,12 @@ static int __cpuinit init_timers_cpu(int cpu) + boot_done = 1; + base = &boot_tvec_bases; + } ++ spin_lock_init(&base->lock); + tvec_base_done[cpu] = 1; + } else { + base = per_cpu(tvec_bases, cpu); + } + +- spin_lock_init(&base->lock); + + for (j = 0; j < TVN_SIZE; j++) { + INIT_LIST_HEAD(base->tv5.vec + j); +diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c +index 431dba8..289197a 100644 +--- a/kernel/trace/trace_events_filter.c ++++ b/kernel/trace/trace_events_filter.c +@@ -777,7 +777,11 @@ static int filter_set_pred(struct event_filter *filter, + + static void __free_preds(struct event_filter *filter) + { ++ int i; ++ + if (filter->preds) { ++ for (i = 0; i < filter->n_preds; i++) ++ kfree(filter->preds[i].ops); + kfree(filter->preds); + filter->preds = NULL; + } +diff --git a/mm/mmap.c b/mm/mmap.c +index 3635d47..ed884dd 100644 +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -1130,15 +1130,19 @@ SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, + file = fget(fd); + if (!file) + goto out; ++ if (is_file_hugepages(file)) ++ len = ALIGN(len, huge_page_size(hstate_file(file))); + } else if (flags & MAP_HUGETLB) { + struct user_struct *user = NULL; ++ ++ len = ALIGN(len, huge_page_size(&default_hstate)); + /* + * VM_NORESERVE is used because the reservations will be + * taken when vm_ops->mmap() is called + * A dummy user value is used because we are not locking + * memory so no accounting is necessary + */ +- file = hugetlb_file_setup(HUGETLB_ANON_FILE, addr, len, ++ file = hugetlb_file_setup(HUGETLB_ANON_FILE, len, + VM_NORESERVE, &user, + HUGETLB_ANONHUGE_INODE); + if (IS_ERR(file)) +diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c +index 9757c19..daeb19d 100644 +--- a/net/8021q/vlan_dev.c ++++ b/net/8021q/vlan_dev.c +@@ -598,7 +598,7 @@ static netdev_features_t vlan_dev_fix_features(struct net_device *dev, + netdev_features_t features) + { + struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; +- u32 old_features = features; ++ netdev_features_t old_features = features; + + features &= real_dev->vlan_features; + features |= NETIF_F_RXCSUM; +diff --git a/net/bridge/br_stp_timer.c b/net/bridge/br_stp_timer.c +index 58de2a0..c83ee79 100644 +--- a/net/bridge/br_stp_timer.c ++++ b/net/bridge/br_stp_timer.c +@@ -107,7 +107,7 @@ static void br_tcn_timer_expired(unsigned long arg) + + br_debug(br, "tcn timer expired\n"); + spin_lock(&br->lock); +- if (br->dev->flags & IFF_UP) { ++ if (!br_is_root_bridge(br) && (br->dev->flags & IFF_UP)) { + br_transmit_tcn(br); + + mod_timer(&br->tcn_timer,jiffies + br->bridge_hello_time); +diff --git a/net/core/dev.c b/net/core/dev.c +index dd12421..7db83d6 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -2170,7 +2170,7 @@ EXPORT_SYMBOL(netif_skb_features); + * support DMA from it. + */ + static inline int skb_needs_linearize(struct sk_buff *skb, +- int features) ++ netdev_features_t features) + { + return skb_is_nonlinear(skb) && + ((skb_has_frag_list(skb) && +diff --git a/net/core/ethtool.c b/net/core/ethtool.c +index 6d6d7d2..7becb3f 100644 +--- a/net/core/ethtool.c ++++ b/net/core/ethtool.c +@@ -1286,7 +1286,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) + void __user *useraddr = ifr->ifr_data; + u32 ethcmd; + int rc; +- u32 old_features; ++ netdev_features_t old_features; + + if (!dev || !netif_device_present(dev)) + return -ENODEV; +diff --git a/net/core/sock.c b/net/core/sock.c +index f8b5030..561eb57 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -1093,18 +1093,6 @@ static void sock_copy(struct sock *nsk, const struct sock *osk) + #endif + } + +-/* +- * caches using SLAB_DESTROY_BY_RCU should let .next pointer from nulls nodes +- * un-modified. Special care is taken when initializing object to zero. +- */ +-static inline void sk_prot_clear_nulls(struct sock *sk, int size) +-{ +- if (offsetof(struct sock, sk_node.next) != 0) +- memset(sk, 0, offsetof(struct sock, sk_node.next)); +- memset(&sk->sk_node.pprev, 0, +- size - offsetof(struct sock, sk_node.pprev)); +-} +- + void sk_prot_clear_portaddr_nulls(struct sock *sk, int size) + { + unsigned long nulls1, nulls2; +diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c +index 3889e02..7ee7121 100644 +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -2079,6 +2079,17 @@ void tcp6_proc_exit(struct net *net) + } + #endif + ++static void tcp_v6_clear_sk(struct sock *sk, int size) ++{ ++ struct inet_sock *inet = inet_sk(sk); ++ ++ /* we do not want to clear pinet6 field, because of RCU lookups */ ++ sk_prot_clear_nulls(sk, offsetof(struct inet_sock, pinet6)); ++ ++ size -= offsetof(struct inet_sock, pinet6) + sizeof(inet->pinet6); ++ memset(&inet->pinet6 + 1, 0, size); ++} ++ + struct proto tcpv6_prot = { + .name = "TCPv6", + .owner = THIS_MODULE, +@@ -2120,6 +2131,7 @@ struct proto tcpv6_prot = { + #ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM + .proto_cgroup = tcp_proto_cgroup, + #endif ++ .clear_sk = tcp_v6_clear_sk, + }; + + static const struct inet6_protocol tcpv6_protocol = { +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c +index 37b0699..aa2f18b 100644 +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -1457,6 +1457,17 @@ void udp6_proc_exit(struct net *net) { + } + #endif /* CONFIG_PROC_FS */ + ++void udp_v6_clear_sk(struct sock *sk, int size) ++{ ++ struct inet_sock *inet = inet_sk(sk); ++ ++ /* we do not want to clear pinet6 field, because of RCU lookups */ ++ sk_prot_clear_portaddr_nulls(sk, offsetof(struct inet_sock, pinet6)); ++ ++ size -= offsetof(struct inet_sock, pinet6) + sizeof(inet->pinet6); ++ memset(&inet->pinet6 + 1, 0, size); ++} ++ + /* ------------------------------------------------------------------------ */ + + struct proto udpv6_prot = { +@@ -1487,7 +1498,7 @@ struct proto udpv6_prot = { + .compat_setsockopt = compat_udpv6_setsockopt, + .compat_getsockopt = compat_udpv6_getsockopt, + #endif +- .clear_sk = sk_prot_clear_portaddr_nulls, ++ .clear_sk = udp_v6_clear_sk, + }; + + static struct inet_protosw udpv6_protosw = { +diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h +index d757104..4691ed5 100644 +--- a/net/ipv6/udp_impl.h ++++ b/net/ipv6/udp_impl.h +@@ -31,6 +31,8 @@ extern int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, + extern int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb); + extern void udpv6_destroy_sock(struct sock *sk); + ++extern void udp_v6_clear_sk(struct sock *sk, int size); ++ + #ifdef CONFIG_PROC_FS + extern int udp6_seq_show(struct seq_file *seq, void *v); + #endif +diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c +index 1d08e21..dfcc4be 100644 +--- a/net/ipv6/udplite.c ++++ b/net/ipv6/udplite.c +@@ -56,7 +56,7 @@ struct proto udplitev6_prot = { + .compat_setsockopt = compat_udpv6_setsockopt, + .compat_getsockopt = compat_udpv6_getsockopt, + #endif +- .clear_sk = sk_prot_clear_portaddr_nulls, ++ .clear_sk = udp_v6_clear_sk, + }; + + static struct inet_protosw udplite6_protosw = { +diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c +index 8ea65e0..808fd08 100644 +--- a/net/ipv6/xfrm6_policy.c ++++ b/net/ipv6/xfrm6_policy.c +@@ -96,8 +96,10 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, + dev_hold(dev); + + xdst->u.rt6.rt6i_idev = in6_dev_get(dev); +- if (!xdst->u.rt6.rt6i_idev) ++ if (!xdst->u.rt6.rt6i_idev) { ++ dev_put(dev); + return -ENODEV; ++ } + + xdst->u.rt6.rt6i_peer = rt->rt6i_peer; + if (rt->rt6i_peer) +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 38ca5e0..cfcd783 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -812,37 +812,27 @@ static void prb_open_block(struct tpacket_kbdq_core *pkc1, + + smp_rmb(); + +- if (likely(TP_STATUS_KERNEL == BLOCK_STATUS(pbd1))) { +- +- /* We could have just memset this but we will lose the +- * flexibility of making the priv area sticky +- */ +- BLOCK_SNUM(pbd1) = pkc1->knxt_seq_num++; +- BLOCK_NUM_PKTS(pbd1) = 0; +- BLOCK_LEN(pbd1) = BLK_PLUS_PRIV(pkc1->blk_sizeof_priv); +- getnstimeofday(&ts); +- h1->ts_first_pkt.ts_sec = ts.tv_sec; +- h1->ts_first_pkt.ts_nsec = ts.tv_nsec; +- pkc1->pkblk_start = (char *)pbd1; +- pkc1->nxt_offset = (char *)(pkc1->pkblk_start + +- BLK_PLUS_PRIV(pkc1->blk_sizeof_priv)); +- BLOCK_O2FP(pbd1) = (__u32)BLK_PLUS_PRIV(pkc1->blk_sizeof_priv); +- BLOCK_O2PRIV(pbd1) = BLK_HDR_LEN; +- pbd1->version = pkc1->version; +- pkc1->prev = pkc1->nxt_offset; +- pkc1->pkblk_end = pkc1->pkblk_start + pkc1->kblk_size; +- prb_thaw_queue(pkc1); +- _prb_refresh_rx_retire_blk_timer(pkc1); +- +- smp_wmb(); +- +- return; +- } ++ /* We could have just memset this but we will lose the ++ * flexibility of making the priv area sticky ++ */ ++ BLOCK_SNUM(pbd1) = pkc1->knxt_seq_num++; ++ BLOCK_NUM_PKTS(pbd1) = 0; ++ BLOCK_LEN(pbd1) = BLK_PLUS_PRIV(pkc1->blk_sizeof_priv); ++ getnstimeofday(&ts); ++ h1->ts_first_pkt.ts_sec = ts.tv_sec; ++ h1->ts_first_pkt.ts_nsec = ts.tv_nsec; ++ pkc1->pkblk_start = (char *)pbd1; ++ pkc1->nxt_offset = (char *)(pkc1->pkblk_start + ++ BLK_PLUS_PRIV(pkc1->blk_sizeof_priv)); ++ BLOCK_O2FP(pbd1) = (__u32)BLK_PLUS_PRIV(pkc1->blk_sizeof_priv); ++ BLOCK_O2PRIV(pbd1) = BLK_HDR_LEN; ++ pbd1->version = pkc1->version; ++ pkc1->prev = pkc1->nxt_offset; ++ pkc1->pkblk_end = pkc1->pkblk_start + pkc1->kblk_size; ++ prb_thaw_queue(pkc1); ++ _prb_refresh_rx_retire_blk_timer(pkc1); + +- WARN(1, "ERROR block:%p is NOT FREE status:%d kactive_blk_num:%d\n", +- pbd1, BLOCK_STATUS(pbd1), pkc1->kactive_blk_num); +- dump_stack(); +- BUG(); ++ smp_wmb(); + } + + /* +@@ -933,10 +923,6 @@ static void prb_retire_current_block(struct tpacket_kbdq_core *pkc, + prb_close_block(pkc, pbd, po, status); + return; + } +- +- WARN(1, "ERROR-pbd[%d]:%p\n", pkc->kactive_blk_num, pbd); +- dump_stack(); +- BUG(); + } + + static int prb_curr_blk_in_use(struct tpacket_kbdq_core *pkc, +diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c +index 60f8f61..57827bf 100644 +--- a/net/sched/act_ipt.c ++++ b/net/sched/act_ipt.c +@@ -8,7 +8,7 @@ + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * +- * Copyright: Jamal Hadi Salim (2002-4) ++ * Copyright: Jamal Hadi Salim (2002-13) + */ + + #include +@@ -299,17 +299,44 @@ static struct tc_action_ops act_ipt_ops = { + .walk = tcf_generic_walker + }; + +-MODULE_AUTHOR("Jamal Hadi Salim(2002-4)"); ++static struct tc_action_ops act_xt_ops = { ++ .kind = "xt", ++ .hinfo = &ipt_hash_info, ++ .type = TCA_ACT_IPT, ++ .capab = TCA_CAP_NONE, ++ .owner = THIS_MODULE, ++ .act = tcf_ipt, ++ .dump = tcf_ipt_dump, ++ .cleanup = tcf_ipt_cleanup, ++ .lookup = tcf_hash_search, ++ .init = tcf_ipt_init, ++ .walk = tcf_generic_walker ++}; ++ ++MODULE_AUTHOR("Jamal Hadi Salim(2002-13)"); + MODULE_DESCRIPTION("Iptables target actions"); + MODULE_LICENSE("GPL"); ++MODULE_ALIAS("act_xt"); + + static int __init ipt_init_module(void) + { +- return tcf_register_action(&act_ipt_ops); ++ int ret1, ret2; ++ ret1 = tcf_register_action(&act_xt_ops); ++ if (ret1 < 0) ++ printk("Failed to load xt action\n"); ++ ret2 = tcf_register_action(&act_ipt_ops); ++ if (ret2 < 0) ++ printk("Failed to load ipt action\n"); ++ ++ if (ret1 < 0 && ret2 < 0) ++ return ret1; ++ else ++ return 0; + } + + static void __exit ipt_cleanup_module(void) + { ++ tcf_unregister_action(&act_xt_ops); + tcf_unregister_action(&act_ipt_ops); + } + +diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c +index c72dce0..c74a044 100644 +--- a/sound/pci/hda/hda_codec.c ++++ b/sound/pci/hda/hda_codec.c +@@ -617,6 +617,9 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex) + struct hda_bus_unsolicited *unsol; + unsigned int wp; + ++ if (!bus || !bus->workq) ++ return 0; ++ + trace_hda_unsol_event(bus, res, res_ex); + unsol = bus->unsol; + if (!unsol) +diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c +index 4c471a5..d9924d7 100644 +--- a/sound/soc/codecs/wm8994.c ++++ b/sound/soc/codecs/wm8994.c +@@ -2824,6 +2824,7 @@ static int wm8994_aif3_hw_params(struct snd_pcm_substream *substream, + default: + return 0; + } ++ break; + default: + return 0; + } diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.46-47.patch b/patch/kernel/sun8i-default/0001-patch-3.4.46-47.patch new file mode 100644 index 000000000..9b7acc137 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.46-47.patch @@ -0,0 +1,143 @@ +diff --git a/Makefile b/Makefile +index 3d88eb8..a85d4eb 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 46 ++SUBLEVEL = 47 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c +index e458acb..6a8776e 100644 +--- a/drivers/gpu/drm/radeon/evergreen.c ++++ b/drivers/gpu/drm/radeon/evergreen.c +@@ -2443,8 +2443,8 @@ int evergreen_mc_init(struct radeon_device *rdev) + rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); + } else { + /* size in MB on evergreen/cayman/tn */ +- rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; +- rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; ++ rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; ++ rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; + } + rdev->mc.visible_vram_size = rdev->mc.aper_size; + r700_vram_gtt_location(rdev, &rdev->mc); +diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c +index f493c64..49b55ed 100644 +--- a/drivers/gpu/drm/radeon/radeon_ttm.c ++++ b/drivers/gpu/drm/radeon/radeon_ttm.c +@@ -744,7 +744,7 @@ int radeon_ttm_init(struct radeon_device *rdev) + return r; + } + DRM_INFO("radeon: %uM of VRAM memory ready\n", +- (unsigned)rdev->mc.real_vram_size / (1024 * 1024)); ++ (unsigned) (rdev->mc.real_vram_size / (1024 * 1024))); + r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT, + rdev->mc.gtt_size >> PAGE_SHIFT); + if (r) { +diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c +index 5508ad7..2dbd585 100644 +--- a/drivers/gpu/drm/radeon/si.c ++++ b/drivers/gpu/drm/radeon/si.c +@@ -2464,8 +2464,8 @@ static int si_mc_init(struct radeon_device *rdev) + rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); + rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); + /* size in MB on si */ +- rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; +- rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; ++ rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; ++ rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; + rdev->mc.visible_vram_size = rdev->mc.aper_size; + si_vram_gtt_location(rdev, &rdev->mc); + radeon_update_bandwidth_info(rdev); +diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c +index a72bf25..56b178a 100644 +--- a/drivers/hwmon/abituguru.c ++++ b/drivers/hwmon/abituguru.c +@@ -1410,14 +1410,18 @@ static int __devinit abituguru_probe(struct platform_device *pdev) + pr_info("found Abit uGuru\n"); + + /* Register sysfs hooks */ +- for (i = 0; i < sysfs_attr_i; i++) +- if (device_create_file(&pdev->dev, +- &data->sysfs_attr[i].dev_attr)) ++ for (i = 0; i < sysfs_attr_i; i++) { ++ res = device_create_file(&pdev->dev, ++ &data->sysfs_attr[i].dev_attr); ++ if (res) + goto abituguru_probe_error; +- for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) +- if (device_create_file(&pdev->dev, +- &abituguru_sysfs_attr[i].dev_attr)) ++ } ++ for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) { ++ res = device_create_file(&pdev->dev, ++ &abituguru_sysfs_attr[i].dev_attr); ++ if (res) + goto abituguru_probe_error; ++ } + + data->hwmon_dev = hwmon_device_register(&pdev->dev); + if (!IS_ERR(data->hwmon_dev)) +diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c +index 6193349..3c2812f 100644 +--- a/drivers/i2c/busses/i2c-designware-core.c ++++ b/drivers/i2c/busses/i2c-designware-core.c +@@ -349,7 +349,8 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) + /* Enable the adapter */ + dw_writel(dev, 1, DW_IC_ENABLE); + +- /* Enable interrupts */ ++ /* Clear and enable interrupts */ ++ i2c_dw_clear_int(dev); + dw_writel(dev, DW_IC_INTR_DEFAULT_MASK, DW_IC_INTR_MASK); + } + +diff --git a/drivers/media/dvb/mantis/mantis_dvb.c b/drivers/media/dvb/mantis/mantis_dvb.c +index e5180e4..5d15c6b 100644 +--- a/drivers/media/dvb/mantis/mantis_dvb.c ++++ b/drivers/media/dvb/mantis/mantis_dvb.c +@@ -248,8 +248,10 @@ int __devinit mantis_dvb_init(struct mantis_pci *mantis) + err5: + tasklet_kill(&mantis->tasklet); + dvb_net_release(&mantis->dvbnet); +- dvb_unregister_frontend(mantis->fe); +- dvb_frontend_detach(mantis->fe); ++ if (mantis->fe) { ++ dvb_unregister_frontend(mantis->fe); ++ dvb_frontend_detach(mantis->fe); ++ } + err4: + mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem); + +diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c +index 14f8e1f..3a65f43 100644 +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -1653,7 +1653,11 @@ static noinline int copy_to_sk(struct btrfs_root *root, + item_off = btrfs_item_ptr_offset(leaf, i); + item_len = btrfs_item_size_nr(leaf, i); + +- if (item_len > BTRFS_SEARCH_ARGS_BUFSIZE) ++ btrfs_item_key_to_cpu(leaf, key, i); ++ if (!key_in_sk(key, sk)) ++ continue; ++ ++ if (sizeof(sh) + item_len > BTRFS_SEARCH_ARGS_BUFSIZE) + item_len = 0; + + if (sizeof(sh) + item_len + *sk_offset > +@@ -1662,10 +1666,6 @@ static noinline int copy_to_sk(struct btrfs_root *root, + goto overflow; + } + +- btrfs_item_key_to_cpu(leaf, key, i); +- if (!key_in_sk(key, sk)) +- continue; +- + sh.objectid = key->objectid; + sh.offset = key->offset; + sh.type = key->type; diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.47-48.patch b/patch/kernel/sun8i-default/0001-patch-3.4.47-48.patch new file mode 100644 index 000000000..e6516e8e5 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.47-48.patch @@ -0,0 +1,1377 @@ +diff --git a/Makefile b/Makefile +index a85d4eb..65c0d7f 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 47 ++SUBLEVEL = 48 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/arm/mach-kirkwood/ts219-setup.c b/arch/arm/mach-kirkwood/ts219-setup.c +index 73e2b6c..3a73fc7 100644 +--- a/arch/arm/mach-kirkwood/ts219-setup.c ++++ b/arch/arm/mach-kirkwood/ts219-setup.c +@@ -124,7 +124,7 @@ static void __init qnap_ts219_init(void) + static int __init ts219_pci_init(void) + { + if (machine_is_ts219()) +- kirkwood_pcie_init(KW_PCIE0); ++ kirkwood_pcie_init(KW_PCIE1 | KW_PCIE0); + + return 0; + } +diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c +index 331f8bb..4dac6e0 100644 +--- a/arch/arm/plat-orion/common.c ++++ b/arch/arm/plat-orion/common.c +@@ -340,7 +340,7 @@ static struct resource orion_ge10_shared_resources[] = { + + static struct platform_device orion_ge10_shared = { + .name = MV643XX_ETH_SHARED_NAME, +- .id = 1, ++ .id = 2, + .dev = { + .platform_data = &orion_ge10_shared_data, + }, +@@ -355,8 +355,8 @@ static struct resource orion_ge10_resources[] = { + + static struct platform_device orion_ge10 = { + .name = MV643XX_ETH_NAME, +- .id = 1, +- .num_resources = 2, ++ .id = 2, ++ .num_resources = 1, + .resource = orion_ge10_resources, + .dev = { + .coherent_dma_mask = DMA_BIT_MASK(32), +@@ -393,7 +393,7 @@ static struct resource orion_ge11_shared_resources[] = { + + static struct platform_device orion_ge11_shared = { + .name = MV643XX_ETH_SHARED_NAME, +- .id = 1, ++ .id = 3, + .dev = { + .platform_data = &orion_ge11_shared_data, + }, +@@ -408,8 +408,8 @@ static struct resource orion_ge11_resources[] = { + + static struct platform_device orion_ge11 = { + .name = MV643XX_ETH_NAME, +- .id = 1, +- .num_resources = 2, ++ .id = 3, ++ .num_resources = 1, + .resource = orion_ge11_resources, + .dev = { + .coherent_dma_mask = DMA_BIT_MASK(32), +diff --git a/arch/avr32/kernel/module.c b/arch/avr32/kernel/module.c +index 596f730..2c94129 100644 +--- a/arch/avr32/kernel/module.c ++++ b/arch/avr32/kernel/module.c +@@ -264,7 +264,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, + break; + case R_AVR32_GOT18SW: + if ((relocation & 0xfffe0003) != 0 +- && (relocation & 0xfffc0003) != 0xffff0000) ++ && (relocation & 0xfffc0000) != 0xfffc0000) + return reloc_overflow(module, "R_AVR32_GOT18SW", + relocation); + relocation >>= 2; +diff --git a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S +index d197e7f..ac85f16 100644 +--- a/arch/m68k/kernel/head.S ++++ b/arch/m68k/kernel/head.S +@@ -2752,11 +2752,9 @@ func_return get_new_page + #ifdef CONFIG_MAC + + L(scc_initable_mac): +- .byte 9,12 /* Reset */ + .byte 4,0x44 /* x16, 1 stopbit, no parity */ + .byte 3,0xc0 /* receiver: 8 bpc */ + .byte 5,0xe2 /* transmitter: 8 bpc, assert dtr/rts */ +- .byte 9,0 /* no interrupts */ + .byte 10,0 /* NRZ */ + .byte 11,0x50 /* use baud rate generator */ + .byte 12,1,13,0 /* 38400 baud */ +@@ -2899,6 +2897,7 @@ func_start serial_init,%d0/%d1/%a0/%a1 + is_not_mac(L(serial_init_not_mac)) + + #ifdef SERIAL_DEBUG ++ + /* You may define either or both of these. */ + #define MAC_USE_SCC_A /* Modem port */ + #define MAC_USE_SCC_B /* Printer port */ +@@ -2908,9 +2907,21 @@ func_start serial_init,%d0/%d1/%a0/%a1 + #define mac_scc_cha_b_data_offset 0x4 + #define mac_scc_cha_a_data_offset 0x6 + ++#if defined(MAC_USE_SCC_A) || defined(MAC_USE_SCC_B) ++ movel %pc@(L(mac_sccbase)),%a0 ++ /* Reset SCC device */ ++ moveb #9,%a0@(mac_scc_cha_a_ctrl_offset) ++ moveb #0xc0,%a0@(mac_scc_cha_a_ctrl_offset) ++ /* Wait for 5 PCLK cycles, which is about 68 CPU cycles */ ++ /* 5 / 3.6864 MHz = approx. 1.36 us = 68 / 50 MHz */ ++ movel #35,%d0 ++5: ++ subq #1,%d0 ++ jne 5b ++#endif ++ + #ifdef MAC_USE_SCC_A + /* Initialize channel A */ +- movel %pc@(L(mac_sccbase)),%a0 + lea %pc@(L(scc_initable_mac)),%a1 + 5: moveb %a1@+,%d0 + jmi 6f +@@ -2922,9 +2933,6 @@ func_start serial_init,%d0/%d1/%a0/%a1 + + #ifdef MAC_USE_SCC_B + /* Initialize channel B */ +-#ifndef MAC_USE_SCC_A /* Load mac_sccbase only if needed */ +- movel %pc@(L(mac_sccbase)),%a0 +-#endif /* MAC_USE_SCC_A */ + lea %pc@(L(scc_initable_mac)),%a1 + 7: moveb %a1@+,%d0 + jmi 8f +@@ -2933,6 +2941,7 @@ func_start serial_init,%d0/%d1/%a0/%a1 + jra 7b + 8: + #endif /* MAC_USE_SCC_B */ ++ + #endif /* SERIAL_DEBUG */ + + jra L(serial_init_done) +@@ -3006,17 +3015,17 @@ func_start serial_putc,%d0/%d1/%a0/%a1 + + #ifdef SERIAL_DEBUG + +-#ifdef MAC_USE_SCC_A ++#if defined(MAC_USE_SCC_A) || defined(MAC_USE_SCC_B) + movel %pc@(L(mac_sccbase)),%a1 ++#endif ++ ++#ifdef MAC_USE_SCC_A + 3: btst #2,%a1@(mac_scc_cha_a_ctrl_offset) + jeq 3b + moveb %d0,%a1@(mac_scc_cha_a_data_offset) + #endif /* MAC_USE_SCC_A */ + + #ifdef MAC_USE_SCC_B +-#ifndef MAC_USE_SCC_A /* Load mac_sccbase only if needed */ +- movel %pc@(L(mac_sccbase)),%a1 +-#endif /* MAC_USE_SCC_A */ + 4: btst #2,%a1@(mac_scc_cha_b_ctrl_offset) + jeq 4b + moveb %d0,%a1@(mac_scc_cha_b_data_offset) +diff --git a/arch/x86/um/sys_call_table_32.c b/arch/x86/um/sys_call_table_32.c +index 416bd40..68d1dc9 100644 +--- a/arch/x86/um/sys_call_table_32.c ++++ b/arch/x86/um/sys_call_table_32.c +@@ -39,9 +39,9 @@ + #undef __SYSCALL_I386 + #define __SYSCALL_I386(nr, sym, compat) [ nr ] = sym, + +-typedef void (*sys_call_ptr_t)(void); ++typedef asmlinkage void (*sys_call_ptr_t)(void); + +-extern void sys_ni_syscall(void); ++extern asmlinkage void sys_ni_syscall(void); + + const sys_call_ptr_t sys_call_table[] __cacheline_aligned = { + /* +diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c +index f67fc41..af58f9b 100644 +--- a/drivers/ata/ata_piix.c ++++ b/drivers/ata/ata_piix.c +@@ -151,6 +151,7 @@ enum piix_controller_ids { + piix_pata_vmw, /* PIIX4 for VMware, spurious DMA_ERR */ + ich8_sata_snb, + ich8_2port_sata_snb, ++ ich8_2port_sata_byt, + }; + + struct piix_map_db { +@@ -348,6 +349,9 @@ static const struct pci_device_id piix_pci_tbl[] = { + { 0x8086, 0x8d60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, + /* SATA Controller IDE (Wellsburg) */ + { 0x8086, 0x8d68, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, ++ /* SATA Controller IDE (BayTrail) */ ++ { 0x8086, 0x0F20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_byt }, ++ { 0x8086, 0x0F21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_byt }, + + { } /* terminate list */ + }; +@@ -513,6 +517,7 @@ static const struct piix_map_db *piix_map_db_table[] = { + [tolapai_sata] = &tolapai_map_db, + [ich8_sata_snb] = &ich8_map_db, + [ich8_2port_sata_snb] = &ich8_2port_map_db, ++ [ich8_2port_sata_byt] = &ich8_2port_map_db, + }; + + static struct ata_port_info piix_port_info[] = { +@@ -663,6 +668,16 @@ static struct ata_port_info piix_port_info[] = { + .udma_mask = ATA_UDMA6, + .port_ops = &piix_sata_ops, + }, ++ ++ [ich8_2port_sata_byt] = ++ { ++ .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR | PIIX_FLAG_PIO16, ++ .pio_mask = ATA_PIO4, ++ .mwdma_mask = ATA_MWDMA2, ++ .udma_mask = ATA_UDMA6, ++ .port_ops = &piix_sata_ops, ++ }, ++ + }; + + static struct pci_bits piix_enable_bits[] = { +diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c +index 02dd34c..9cf09ae 100644 +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -1599,6 +1599,12 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, + qc->tf = *tf; + if (cdb) + memcpy(qc->cdb, cdb, ATAPI_CDB_LEN); ++ ++ /* some SATA bridges need us to indicate data xfer direction */ ++ if (tf->protocol == ATAPI_PROT_DMA && (dev->flags & ATA_DFLAG_DMADIR) && ++ dma_dir == DMA_FROM_DEVICE) ++ qc->tf.feature |= ATAPI_DMADIR; ++ + qc->flags |= ATA_QCFLAG_RESULT_TF; + qc->dma_dir = dma_dir; + if (dma_dir != DMA_NONE) { +diff --git a/drivers/block/brd.c b/drivers/block/brd.c +index 531ceb3..4e8213a 100644 +--- a/drivers/block/brd.c ++++ b/drivers/block/brd.c +@@ -117,13 +117,13 @@ static struct page *brd_insert_page(struct brd_device *brd, sector_t sector) + + spin_lock(&brd->brd_lock); + idx = sector >> PAGE_SECTORS_SHIFT; ++ page->index = idx; + if (radix_tree_insert(&brd->brd_pages, idx, page)) { + __free_page(page); + page = radix_tree_lookup(&brd->brd_pages, idx); + BUG_ON(!page); + BUG_ON(page->index != idx); +- } else +- page->index = idx; ++ } + spin_unlock(&brd->brd_lock); + + radix_tree_preload_end(); +diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c +index 68c89db..1209f15 100644 +--- a/drivers/gpu/drm/radeon/radeon_device.c ++++ b/drivers/gpu/drm/radeon/radeon_device.c +@@ -363,18 +363,17 @@ bool radeon_card_posted(struct radeon_device *rdev) + return false; + + /* first check CRTCs */ +- if (ASIC_IS_DCE41(rdev)) { ++ if (ASIC_IS_DCE4(rdev)) { + reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | + RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); +- if (reg & EVERGREEN_CRTC_MASTER_EN) +- return true; +- } else if (ASIC_IS_DCE4(rdev)) { +- reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | +- RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) | +- RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) | +- RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET) | +- RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) | +- RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); ++ if (rdev->num_crtc >= 4) { ++ reg |= RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) | ++ RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET); ++ } ++ if (rdev->num_crtc >= 6) { ++ reg |= RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) | ++ RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); ++ } + if (reg & EVERGREEN_CRTC_MASTER_EN) + return true; + } else if (ASIC_IS_AVIVO(rdev)) { +diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c +index 0569843..99a8444 100644 +--- a/drivers/iommu/amd_iommu.c ++++ b/drivers/iommu/amd_iommu.c +@@ -531,11 +531,23 @@ retry: + + static void iommu_poll_events(struct amd_iommu *iommu) + { +- u32 head, tail; ++ u32 head, tail, status; + unsigned long flags; + + spin_lock_irqsave(&iommu->lock, flags); + ++ /* enable event interrupts again */ ++ do { ++ /* ++ * Workaround for Erratum ERBT1312 ++ * Clearing the EVT_INT bit may race in the hardware, so read ++ * it again and make sure it was really cleared ++ */ ++ status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET); ++ writel(MMIO_STATUS_EVT_INT_MASK, ++ iommu->mmio_base + MMIO_STATUS_OFFSET); ++ } while (status & MMIO_STATUS_EVT_INT_MASK); ++ + head = readl(iommu->mmio_base + MMIO_EVT_HEAD_OFFSET); + tail = readl(iommu->mmio_base + MMIO_EVT_TAIL_OFFSET); + +@@ -572,16 +584,25 @@ static void iommu_handle_ppr_entry(struct amd_iommu *iommu, u64 *raw) + static void iommu_poll_ppr_log(struct amd_iommu *iommu) + { + unsigned long flags; +- u32 head, tail; ++ u32 head, tail, status; + + if (iommu->ppr_log == NULL) + return; + +- /* enable ppr interrupts again */ +- writel(MMIO_STATUS_PPR_INT_MASK, iommu->mmio_base + MMIO_STATUS_OFFSET); +- + spin_lock_irqsave(&iommu->lock, flags); + ++ /* enable ppr interrupts again */ ++ do { ++ /* ++ * Workaround for Erratum ERBT1312 ++ * Clearing the PPR_INT bit may race in the hardware, so read ++ * it again and make sure it was really cleared ++ */ ++ status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET); ++ writel(MMIO_STATUS_PPR_INT_MASK, ++ iommu->mmio_base + MMIO_STATUS_OFFSET); ++ } while (status & MMIO_STATUS_PPR_INT_MASK); ++ + head = readl(iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); + tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET); + +diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h +index 2435555..c4ffacb 100644 +--- a/drivers/iommu/amd_iommu_types.h ++++ b/drivers/iommu/amd_iommu_types.h +@@ -99,6 +99,7 @@ + #define PASID_MASK 0x000fffff + + /* MMIO status bits */ ++#define MMIO_STATUS_EVT_INT_MASK (1 << 1) + #define MMIO_STATUS_COM_WAIT_INT_MASK (1 << 2) + #define MMIO_STATUS_PPR_INT_MASK (1 << 6) + +diff --git a/drivers/leds/leds-ot200.c b/drivers/leds/leds-ot200.c +index c464682..676e729 100644 +--- a/drivers/leds/leds-ot200.c ++++ b/drivers/leds/leds-ot200.c +@@ -47,37 +47,37 @@ static struct ot200_led leds[] = { + { + .name = "led_1", + .port = 0x49, +- .mask = BIT(7), ++ .mask = BIT(6), + }, + { + .name = "led_2", + .port = 0x49, +- .mask = BIT(6), ++ .mask = BIT(5), + }, + { + .name = "led_3", + .port = 0x49, +- .mask = BIT(5), ++ .mask = BIT(4), + }, + { + .name = "led_4", + .port = 0x49, +- .mask = BIT(4), ++ .mask = BIT(3), + }, + { + .name = "led_5", + .port = 0x49, +- .mask = BIT(3), ++ .mask = BIT(2), + }, + { + .name = "led_6", + .port = 0x49, +- .mask = BIT(2), ++ .mask = BIT(1), + }, + { + .name = "led_7", + .port = 0x49, +- .mask = BIT(1), ++ .mask = BIT(0), + } + }; + +diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c +index 2bdf798..0d22cff 100644 +--- a/drivers/net/xen-netback/netback.c ++++ b/drivers/net/xen-netback/netback.c +@@ -914,7 +914,6 @@ static int netbk_count_requests(struct xenvif *vif, + } + + static struct page *xen_netbk_alloc_page(struct xen_netbk *netbk, +- struct sk_buff *skb, + u16 pending_idx) + { + struct page *page; +@@ -948,7 +947,7 @@ static struct gnttab_copy *xen_netbk_get_requests(struct xen_netbk *netbk, + + index = pending_index(netbk->pending_cons++); + pending_idx = netbk->pending_ring[index]; +- page = xen_netbk_alloc_page(netbk, skb, pending_idx); ++ page = xen_netbk_alloc_page(netbk, pending_idx); + if (!page) + goto err; + +@@ -1353,7 +1352,7 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) + } + + /* XXX could copy straight to head */ +- page = xen_netbk_alloc_page(netbk, skb, pending_idx); ++ page = xen_netbk_alloc_page(netbk, pending_idx); + if (!page) { + kfree_skb(skb); + netbk_tx_err(vif, &txreq, idx); +diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c +index d68c000..f08aee6 100644 +--- a/drivers/platform/x86/thinkpad_acpi.c ++++ b/drivers/platform/x86/thinkpad_acpi.c +@@ -8662,6 +8662,13 @@ static int __must_check __init get_thinkpad_model_data( + tp->model_str = kstrdup(s, GFP_KERNEL); + if (!tp->model_str) + return -ENOMEM; ++ } else { ++ s = dmi_get_system_info(DMI_BIOS_VENDOR); ++ if (s && !(strnicmp(s, "Lenovo", 6))) { ++ tp->model_str = kstrdup(s, GFP_KERNEL); ++ if (!tp->model_str) ++ return -ENOMEM; ++ } + } + + s = dmi_get_system_info(DMI_PRODUCT_NAME); +diff --git a/drivers/staging/vt6656/hostap.c b/drivers/staging/vt6656/hostap.c +index 51b5adf..df8ea25 100644 +--- a/drivers/staging/vt6656/hostap.c ++++ b/drivers/staging/vt6656/hostap.c +@@ -153,7 +153,7 @@ static int hostap_disable_hostapd(PSDevice pDevice, int rtnl_locked) + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n", + pDevice->dev->name, pDevice->apdev->name); + } +- kfree(pDevice->apdev); ++ free_netdev(pDevice->apdev); + pDevice->apdev = NULL; + pDevice->bEnable8021x = FALSE; + pDevice->bEnableHostWEP = FALSE; +diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c +index eb05c9d..8a8ff23 100644 +--- a/drivers/target/iscsi/iscsi_target_parameters.c ++++ b/drivers/target/iscsi/iscsi_target_parameters.c +@@ -713,9 +713,9 @@ static int iscsi_add_notunderstood_response( + } + INIT_LIST_HEAD(&extra_response->er_list); + +- strncpy(extra_response->key, key, strlen(key) + 1); +- strncpy(extra_response->value, NOTUNDERSTOOD, +- strlen(NOTUNDERSTOOD) + 1); ++ strlcpy(extra_response->key, key, sizeof(extra_response->key)); ++ strlcpy(extra_response->value, NOTUNDERSTOOD, ++ sizeof(extra_response->value)); + + list_add_tail(&extra_response->er_list, + ¶m_list->extra_response_list); +@@ -1571,8 +1571,6 @@ int iscsi_decode_text_input( + + if (phase & PHASE_SECURITY) { + if (iscsi_check_for_auth_key(key) > 0) { +- char *tmpptr = key + strlen(key); +- *tmpptr = '='; + kfree(tmpbuf); + return 1; + } +diff --git a/drivers/target/iscsi/iscsi_target_parameters.h b/drivers/target/iscsi/iscsi_target_parameters.h +index 6a37fd6..83eed65 100644 +--- a/drivers/target/iscsi/iscsi_target_parameters.h ++++ b/drivers/target/iscsi/iscsi_target_parameters.h +@@ -1,8 +1,10 @@ + #ifndef ISCSI_PARAMETERS_H + #define ISCSI_PARAMETERS_H + ++#include ++ + struct iscsi_extra_response { +- char key[64]; ++ char key[KEY_MAXLEN]; + char value[32]; + struct list_head er_list; + } ____cacheline_aligned; +diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c +index 2303a02..37818fb 100644 +--- a/drivers/tty/n_tty.c ++++ b/drivers/tty/n_tty.c +@@ -1529,6 +1529,14 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) + tty->real_raw = 0; + } + n_tty_set_room(tty); ++ /* ++ * Fix tty hang when I_IXON(tty) is cleared, but the tty ++ * been stopped by STOP_CHAR(tty) before it. ++ */ ++ if (!I_IXON(tty) && old && (old->c_iflag & IXON) && !tty->flow_stopped) { ++ start_tty(tty); ++ } ++ + /* The termios change make the tty ready for I/O */ + wake_up_interruptible(&tty->write_wait); + wake_up_interruptible(&tty->read_wait); +diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c +index 98b89fe..c8dbb97 100644 +--- a/drivers/usb/atm/cxacru.c ++++ b/drivers/usb/atm/cxacru.c +@@ -686,7 +686,8 @@ static int cxacru_cm_get_array(struct cxacru_data *instance, enum cxacru_cm_requ + { + int ret, len; + __le32 *buf; +- int offb, offd; ++ int offb; ++ unsigned int offd; + const int stride = CMD_PACKET_SIZE / (4 * 2) - 1; + int buflen = ((size - 1) / stride + 1 + size * 2) * 4; + +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index 8b2a9d8..f88ad63 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -110,6 +110,9 @@ static const struct usb_device_id usb_quirk_list[] = { + /* Edirol SD-20 */ + { USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME }, + ++ /* Alcor Micro Corp. Hub */ ++ { USB_DEVICE(0x058f, 0x9254), .driver_info = USB_QUIRK_RESET_RESUME }, ++ + /* appletouch */ + { USB_DEVICE(0x05ac, 0x021a), .driver_info = USB_QUIRK_RESET_RESUME }, + +diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c +index 768d542..c994655 100644 +--- a/drivers/usb/host/uhci-hub.c ++++ b/drivers/usb/host/uhci-hub.c +@@ -222,7 +222,8 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf) + /* auto-stop if nothing connected for 1 second */ + if (any_ports_active(uhci)) + uhci->rh_state = UHCI_RH_RUNNING; +- else if (time_after_eq(jiffies, uhci->auto_stop_time)) ++ else if (time_after_eq(jiffies, uhci->auto_stop_time) && ++ !uhci->wait_for_hp) + suspend_rh(uhci, UHCI_RH_AUTO_STOPPED); + break; + +diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c +index b42a6fb..f059222 100644 +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -1443,15 +1443,17 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, + ep_ctx->ep_info2 |= cpu_to_le32(xhci_get_endpoint_type(udev, ep)); + + /* Set the max packet size and max burst */ ++ max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc)); ++ max_burst = 0; + switch (udev->speed) { + case USB_SPEED_SUPER: +- max_packet = usb_endpoint_maxp(&ep->desc); +- ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet)); + /* dig out max burst from ep companion desc */ +- max_packet = ep->ss_ep_comp.bMaxBurst; +- ep_ctx->ep_info2 |= cpu_to_le32(MAX_BURST(max_packet)); ++ max_burst = ep->ss_ep_comp.bMaxBurst; + break; + case USB_SPEED_HIGH: ++ /* Some devices get this wrong */ ++ if (usb_endpoint_xfer_bulk(&ep->desc)) ++ max_packet = 512; + /* bits 11:12 specify the number of additional transaction + * opportunities per microframe (USB 2.0, section 9.6.6) + */ +@@ -1459,17 +1461,16 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, + usb_endpoint_xfer_int(&ep->desc)) { + max_burst = (usb_endpoint_maxp(&ep->desc) + & 0x1800) >> 11; +- ep_ctx->ep_info2 |= cpu_to_le32(MAX_BURST(max_burst)); + } +- /* Fall through */ ++ break; + case USB_SPEED_FULL: + case USB_SPEED_LOW: +- max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc)); +- ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet)); + break; + default: + BUG(); + } ++ ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet) | ++ MAX_BURST(max_burst)); + max_esit_payload = xhci_get_max_esit_payload(xhci, udev, ep); + ep_ctx->tx_info = cpu_to_le32(MAX_ESIT_PAYLOAD_FOR_EP(max_esit_payload)); + +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index e5ccafc..c6f8e62 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -199,6 +199,8 @@ static struct usb_device_id id_table_combined [] = { + { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_BOOST_PID) }, + { USB_DEVICE(NEWPORT_VID, NEWPORT_AGILIS_PID) }, ++ { USB_DEVICE(NEWPORT_VID, NEWPORT_CONEX_CC_PID) }, ++ { USB_DEVICE(NEWPORT_VID, NEWPORT_CONEX_AGP_PID) }, + { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, + { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) }, +diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h +index 9852827..6dd7925 100644 +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -772,6 +772,8 @@ + */ + #define NEWPORT_VID 0x104D + #define NEWPORT_AGILIS_PID 0x3000 ++#define NEWPORT_CONEX_CC_PID 0x3002 ++#define NEWPORT_CONEX_AGP_PID 0x3006 + + /* Interbiometrics USB I/O Board */ + /* Developed for Interbiometrics by Rudolf Gugler */ +diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c +index 7e8bb8f..b68efdc 100644 +--- a/drivers/usb/serial/io_ti.c ++++ b/drivers/usb/serial/io_ti.c +@@ -550,6 +550,9 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout, + wait_queue_t wait; + unsigned long flags; + ++ if (!tty) ++ return; ++ + if (!timeout) + timeout = (HZ * EDGE_CLOSING_WAIT)/100; + +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 16efe0a..386b3ab 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -196,6 +196,7 @@ static void option_instat_callback(struct urb *urb); + + #define DELL_PRODUCT_5800_MINICARD_VZW 0x8195 /* Novatel E362 */ + #define DELL_PRODUCT_5800_V2_MINICARD_VZW 0x8196 /* Novatel E362 */ ++#define DELL_PRODUCT_5804_MINICARD_ATT 0x819b /* Novatel E371 */ + + #define KYOCERA_VENDOR_ID 0x0c88 + #define KYOCERA_PRODUCT_KPC650 0x17da +@@ -341,8 +342,8 @@ static void option_instat_callback(struct urb *urb); + #define CINTERION_PRODUCT_EU3_E 0x0051 + #define CINTERION_PRODUCT_EU3_P 0x0052 + #define CINTERION_PRODUCT_PH8 0x0053 +-#define CINTERION_PRODUCT_AH6 0x0055 +-#define CINTERION_PRODUCT_PLS8 0x0060 ++#define CINTERION_PRODUCT_AHXX 0x0055 ++#define CINTERION_PRODUCT_PLXX 0x0060 + + /* Olivetti products */ + #define OLIVETTI_VENDOR_ID 0x0b3c +@@ -771,6 +772,7 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ + { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_MINICARD_VZW, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_V2_MINICARD_VZW, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5804_MINICARD_ATT, 0xff, 0xff, 0xff) }, + { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ + { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, + { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, +@@ -966,6 +968,8 @@ static const struct usb_device_id option_ids[] = { + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { 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 }, + { 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), +@@ -1264,8 +1268,9 @@ 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) }, +- { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AH6) }, +- { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLS8) }, ++ { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX) }, ++ { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX), ++ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, + { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) }, +diff --git a/drivers/xen/events.c b/drivers/xen/events.c +index 26c47a4..417c133 100644 +--- a/drivers/xen/events.c ++++ b/drivers/xen/events.c +@@ -1258,7 +1258,7 @@ static void __xen_evtchn_do_upcall(void) + { + int start_word_idx, start_bit_idx; + int word_idx, bit_idx; +- int i; ++ int i, irq; + int cpu = get_cpu(); + struct shared_info *s = HYPERVISOR_shared_info; + struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu); +@@ -1266,6 +1266,8 @@ static void __xen_evtchn_do_upcall(void) + + do { + unsigned long pending_words; ++ unsigned long pending_bits; ++ struct irq_desc *desc; + + vcpu_info->evtchn_upcall_pending = 0; + +@@ -1276,6 +1278,17 @@ static void __xen_evtchn_do_upcall(void) + /* Clear master flag /before/ clearing selector flag. */ + wmb(); + #endif ++ if ((irq = per_cpu(virq_to_irq, cpu)[VIRQ_TIMER]) != -1) { ++ int evtchn = evtchn_from_irq(irq); ++ word_idx = evtchn / BITS_PER_LONG; ++ pending_bits = evtchn % BITS_PER_LONG; ++ if (active_evtchns(cpu, s, word_idx) & (1ULL << pending_bits)) { ++ desc = irq_to_desc(irq); ++ if (desc) ++ generic_handle_irq_desc(irq, desc); ++ } ++ } ++ + pending_words = xchg(&vcpu_info->evtchn_pending_sel, 0); + + start_word_idx = __this_cpu_read(current_word_idx); +@@ -1284,7 +1297,6 @@ static void __xen_evtchn_do_upcall(void) + word_idx = start_word_idx; + + for (i = 0; pending_words != 0; i++) { +- unsigned long pending_bits; + unsigned long words; + + words = MASK_LSBS(pending_words, word_idx); +@@ -1313,8 +1325,7 @@ static void __xen_evtchn_do_upcall(void) + + do { + unsigned long bits; +- int port, irq; +- struct irq_desc *desc; ++ int port; + + bits = MASK_LSBS(pending_bits, bit_idx); + +diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c +index 2263144..d0e5fc5 100644 +--- a/fs/cifs/cifs_dfs_ref.c ++++ b/fs/cifs/cifs_dfs_ref.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + #include "cifsglob.h" + #include "cifsproto.h" + #include "cifsfs.h" +@@ -150,7 +151,8 @@ char *cifs_compose_mount_options(const char *sb_mountdata, + * assuming that we have 'unc=' and 'ip=' in + * the original sb_mountdata + */ +- md_len = strlen(sb_mountdata) + rc + strlen(ref->node_name) + 12; ++ md_len = strlen(sb_mountdata) + rc + strlen(ref->node_name) + 12 + ++ INET6_ADDRSTRLEN; + mountdata = kzalloc(md_len+1, GFP_KERNEL); + if (mountdata == NULL) { + rc = -ENOMEM; +diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c +index 745da3d..6fbfbdb 100644 +--- a/fs/cifs/inode.c ++++ b/fs/cifs/inode.c +@@ -173,7 +173,8 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) + + if (fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL) + inode->i_flags |= S_AUTOMOUNT; +- cifs_set_ops(inode); ++ if (inode->i_state & I_NEW) ++ cifs_set_ops(inode); + } + + void +diff --git a/fs/fat/inode.c b/fs/fat/inode.c +index 21687e3..44ae375 100644 +--- a/fs/fat/inode.c ++++ b/fs/fat/inode.c +@@ -1237,6 +1237,19 @@ static int fat_read_root(struct inode *inode) + return 0; + } + ++static unsigned long calc_fat_clusters(struct super_block *sb) ++{ ++ struct msdos_sb_info *sbi = MSDOS_SB(sb); ++ ++ /* Divide first to avoid overflow */ ++ if (sbi->fat_bits != 12) { ++ unsigned long ent_per_sec = sb->s_blocksize * 8 / sbi->fat_bits; ++ return ent_per_sec * sbi->fat_length; ++ } ++ ++ return sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits; ++} ++ + /* + * Read the super block of an MS-DOS FS. + */ +@@ -1433,7 +1446,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, + sbi->fat_bits = (total_clusters > MAX_FAT12) ? 16 : 12; + + /* check that FAT table does not overflow */ +- fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits; ++ fat_clusters = calc_fat_clusters(sb); + total_clusters = min(total_clusters, fat_clusters - FAT_START_ENT); + if (total_clusters > MAX_FAT(sb)) { + if (!silent) +diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c +index 77b69b2..13fc885 100644 +--- a/fs/jfs/inode.c ++++ b/fs/jfs/inode.c +@@ -125,7 +125,7 @@ int jfs_write_inode(struct inode *inode, struct writeback_control *wbc) + { + int wait = wbc->sync_mode == WB_SYNC_ALL; + +- if (test_cflag(COMMIT_Nolink, inode)) ++ if (inode->i_nlink == 0) + return 0; + /* + * If COMMIT_DIRTY is not set, the inode isn't really dirty. +diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c +index 2eb952c..cbe48ea 100644 +--- a/fs/jfs/jfs_logmgr.c ++++ b/fs/jfs/jfs_logmgr.c +@@ -1058,7 +1058,8 @@ static int lmLogSync(struct jfs_log * log, int hard_sync) + */ + void jfs_syncpt(struct jfs_log *log, int hard_sync) + { LOG_LOCK(log); +- lmLogSync(log, hard_sync); ++ if (!test_bit(log_QUIESCE, &log->flag)) ++ lmLogSync(log, hard_sync); + LOG_UNLOCK(log); + } + +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 04f449c..d121c67 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -1053,7 +1053,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata) + struct nfs4_state *state = opendata->state; + struct nfs_inode *nfsi = NFS_I(state->inode); + struct nfs_delegation *delegation; +- int open_mode = opendata->o_arg.open_flags & (O_EXCL|O_TRUNC); ++ int open_mode = opendata->o_arg.open_flags; + fmode_t fmode = opendata->o_arg.fmode; + nfs4_stateid stateid; + int ret = -EAGAIN; +diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c +index 8f7b95a..aa526be 100644 +--- a/fs/nilfs2/inode.c ++++ b/fs/nilfs2/inode.c +@@ -195,13 +195,32 @@ static int nilfs_writepage(struct page *page, struct writeback_control *wbc) + + static int nilfs_set_page_dirty(struct page *page) + { +- int ret = __set_page_dirty_buffers(page); ++ int ret = __set_page_dirty_nobuffers(page); + +- if (ret) { ++ if (page_has_buffers(page)) { + struct inode *inode = page->mapping->host; +- unsigned nr_dirty = 1 << (PAGE_SHIFT - inode->i_blkbits); ++ unsigned nr_dirty = 0; ++ struct buffer_head *bh, *head; + +- nilfs_set_file_dirty(inode, nr_dirty); ++ /* ++ * This page is locked by callers, and no other thread ++ * concurrently marks its buffers dirty since they are ++ * only dirtied through routines in fs/buffer.c in ++ * which call sites of mark_buffer_dirty are protected ++ * by page lock. ++ */ ++ bh = head = page_buffers(page); ++ do { ++ /* Do not mark hole blocks dirty */ ++ if (buffer_dirty(bh) || !buffer_mapped(bh)) ++ continue; ++ ++ set_buffer_dirty(bh); ++ nr_dirty++; ++ } while (bh = bh->b_this_page, bh != head); ++ ++ if (nr_dirty) ++ nilfs_set_file_dirty(inode, nr_dirty); + } + return ret; + } +diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c +index 2f5b92e..7eb1c0c 100644 +--- a/fs/ocfs2/extent_map.c ++++ b/fs/ocfs2/extent_map.c +@@ -791,7 +791,7 @@ int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, + &hole_size, &rec, &is_last); + if (ret) { + mlog_errno(ret); +- goto out; ++ goto out_unlock; + } + + if (rec.e_blkno == 0ULL) { +diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c +index 3011b87..23c79ca 100644 +--- a/fs/xfs/xfs_iops.c ++++ b/fs/xfs/xfs_iops.c +@@ -457,6 +457,28 @@ xfs_vn_getattr( + return 0; + } + ++static void ++xfs_setattr_mode( ++ struct xfs_trans *tp, ++ struct xfs_inode *ip, ++ struct iattr *iattr) ++{ ++ struct inode *inode = VFS_I(ip); ++ umode_t mode = iattr->ia_mode; ++ ++ ASSERT(tp); ++ ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); ++ ++ if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) ++ mode &= ~S_ISGID; ++ ++ ip->i_d.di_mode &= S_IFMT; ++ ip->i_d.di_mode |= mode & ~S_IFMT; ++ ++ inode->i_mode &= S_IFMT; ++ inode->i_mode |= mode & ~S_IFMT; ++} ++ + int + xfs_setattr_nonsize( + struct xfs_inode *ip, +@@ -608,18 +630,8 @@ xfs_setattr_nonsize( + /* + * Change file access modes. + */ +- if (mask & ATTR_MODE) { +- umode_t mode = iattr->ia_mode; +- +- if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) +- mode &= ~S_ISGID; +- +- ip->i_d.di_mode &= S_IFMT; +- ip->i_d.di_mode |= mode & ~S_IFMT; +- +- inode->i_mode &= S_IFMT; +- inode->i_mode |= mode & ~S_IFMT; +- } ++ if (mask & ATTR_MODE) ++ xfs_setattr_mode(tp, ip, iattr); + + /* + * Change file access or modified times. +@@ -716,9 +728,8 @@ xfs_setattr_size( + return XFS_ERROR(error); + + ASSERT(S_ISREG(ip->i_d.di_mode)); +- ASSERT((mask & (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET| +- ATTR_MTIME_SET|ATTR_KILL_SUID|ATTR_KILL_SGID| +- ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0); ++ ASSERT((mask & (ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET| ++ ATTR_MTIME_SET|ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0); + + lock_flags = XFS_ILOCK_EXCL; + if (!(flags & XFS_ATTR_NOLOCK)) +@@ -861,6 +872,12 @@ xfs_setattr_size( + xfs_iflags_set(ip, XFS_ITRUNCATED); + } + ++ /* ++ * Change file access modes. ++ */ ++ if (mask & ATTR_MODE) ++ xfs_setattr_mode(tp, ip, iattr); ++ + if (mask & ATTR_CTIME) { + inode->i_ctime = iattr->ia_ctime; + ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec; +diff --git a/include/linux/wait.h b/include/linux/wait.h +index 1dee81c..6c6c20e 100644 +--- a/include/linux/wait.h ++++ b/include/linux/wait.h +@@ -233,6 +233,8 @@ do { \ + if (!ret) \ + break; \ + } \ ++ if (!ret && (condition)) \ ++ ret = 1; \ + finish_wait(&wq, &__wait); \ + } while (0) + +@@ -249,8 +251,9 @@ do { \ + * wake_up() has to be called after changing any variable that could + * change the result of the wait condition. + * +- * The function returns 0 if the @timeout elapsed, and the remaining +- * jiffies if the condition evaluated to true before the timeout elapsed. ++ * The function returns 0 if the @timeout elapsed, or the remaining ++ * jiffies (at least 1) if the @condition evaluated to %true before ++ * the @timeout elapsed. + */ + #define wait_event_timeout(wq, condition, timeout) \ + ({ \ +@@ -318,6 +321,8 @@ do { \ + ret = -ERESTARTSYS; \ + break; \ + } \ ++ if (!ret && (condition)) \ ++ ret = 1; \ + finish_wait(&wq, &__wait); \ + } while (0) + +@@ -334,9 +339,10 @@ do { \ + * wake_up() has to be called after changing any variable that could + * change the result of the wait condition. + * +- * The function returns 0 if the @timeout elapsed, -ERESTARTSYS if it +- * was interrupted by a signal, and the remaining jiffies otherwise +- * if the condition evaluated to true before the timeout elapsed. ++ * Returns: ++ * 0 if the @timeout elapsed, -%ERESTARTSYS if it was interrupted by ++ * a signal, or the remaining jiffies (at least 1) if the @condition ++ * evaluated to %true before the @timeout elapsed. + */ + #define wait_event_interruptible_timeout(wq, condition, timeout) \ + ({ \ +diff --git a/mm/huge_memory.c b/mm/huge_memory.c +index caf15b6..ef99c15 100644 +--- a/mm/huge_memory.c ++++ b/mm/huge_memory.c +@@ -1949,7 +1949,12 @@ static void collapse_huge_page(struct mm_struct *mm, + pte_unmap(pte); + spin_lock(&mm->page_table_lock); + BUG_ON(!pmd_none(*pmd)); +- set_pmd_at(mm, address, pmd, _pmd); ++ /* ++ * We can only use set_pmd_at when establishing ++ * hugepmds and never for establishing regular pmds that ++ * points to regular pagetables. Use pmd_populate for that ++ */ ++ pmd_populate(mm, pmd, pmd_pgtable(_pmd)); + spin_unlock(&mm->page_table_lock); + anon_vma_unlock(vma->anon_vma); + goto out; +diff --git a/mm/migrate.c b/mm/migrate.c +index 1107238..37cd07b 100644 +--- a/mm/migrate.c ++++ b/mm/migrate.c +@@ -145,7 +145,7 @@ static int remove_migration_pte(struct page *new, struct vm_area_struct *vma, + if (PageHuge(new)) + pte = pte_mkhuge(pte); + #endif +- flush_cache_page(vma, addr, pte_pfn(pte)); ++ flush_dcache_page(new); + set_pte_at(mm, addr, ptep, pte); + + if (PageHuge(new)) { +diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c +index 8d1ca2d..c1f947b 100644 +--- a/mm/mmu_notifier.c ++++ b/mm/mmu_notifier.c +@@ -37,51 +37,48 @@ static struct srcu_struct srcu; + void __mmu_notifier_release(struct mm_struct *mm) + { + struct mmu_notifier *mn; ++ struct hlist_node *node; + int id; + + /* +- * srcu_read_lock() here will block synchronize_srcu() in +- * mmu_notifier_unregister() until all registered +- * ->release() callouts this function makes have +- * returned. ++ * SRCU here will block mmu_notifier_unregister until ++ * ->release returns. + */ + id = srcu_read_lock(&srcu); ++ hlist_for_each_entry_rcu(mn, node, &mm->mmu_notifier_mm->list, hlist) ++ /* ++ * If ->release runs before mmu_notifier_unregister it must be ++ * handled, as it's the only way for the driver to flush all ++ * existing sptes and stop the driver from establishing any more ++ * sptes before all the pages in the mm are freed. ++ */ ++ if (mn->ops->release) ++ mn->ops->release(mn, mm); ++ srcu_read_unlock(&srcu, id); ++ + spin_lock(&mm->mmu_notifier_mm->lock); + while (unlikely(!hlist_empty(&mm->mmu_notifier_mm->list))) { + mn = hlist_entry(mm->mmu_notifier_mm->list.first, + struct mmu_notifier, + hlist); +- + /* +- * Unlink. This will prevent mmu_notifier_unregister() +- * from also making the ->release() callout. ++ * We arrived before mmu_notifier_unregister so ++ * mmu_notifier_unregister will do nothing other than to wait ++ * for ->release to finish and for mmu_notifier_unregister to ++ * return. + */ + hlist_del_init_rcu(&mn->hlist); +- spin_unlock(&mm->mmu_notifier_mm->lock); +- +- /* +- * Clear sptes. (see 'release' description in mmu_notifier.h) +- */ +- if (mn->ops->release) +- mn->ops->release(mn, mm); +- +- spin_lock(&mm->mmu_notifier_mm->lock); + } + spin_unlock(&mm->mmu_notifier_mm->lock); + + /* +- * All callouts to ->release() which we have done are complete. +- * Allow synchronize_srcu() in mmu_notifier_unregister() to complete +- */ +- srcu_read_unlock(&srcu, id); +- +- /* +- * mmu_notifier_unregister() may have unlinked a notifier and may +- * still be calling out to it. Additionally, other notifiers +- * may have been active via vmtruncate() et. al. Block here +- * to ensure that all notifier callouts for this mm have been +- * completed and the sptes are really cleaned up before returning +- * to exit_mmap(). ++ * synchronize_srcu here prevents mmu_notifier_release from returning to ++ * exit_mmap (which would proceed with freeing all pages in the mm) ++ * until the ->release method returns, if it was invoked by ++ * mmu_notifier_unregister. ++ * ++ * The mmu_notifier_mm can't go away from under us because one mm_count ++ * is held by exit_mmap. + */ + synchronize_srcu(&srcu); + } +@@ -302,31 +299,34 @@ void mmu_notifier_unregister(struct mmu_notifier *mn, struct mm_struct *mm) + { + BUG_ON(atomic_read(&mm->mm_count) <= 0); + +- spin_lock(&mm->mmu_notifier_mm->lock); + if (!hlist_unhashed(&mn->hlist)) { ++ /* ++ * SRCU here will force exit_mmap to wait for ->release to ++ * finish before freeing the pages. ++ */ + int id; + ++ id = srcu_read_lock(&srcu); + /* +- * Ensure we synchronize up with __mmu_notifier_release(). ++ * exit_mmap will block in mmu_notifier_release to guarantee ++ * that ->release is called before freeing the pages. + */ +- id = srcu_read_lock(&srcu); +- +- hlist_del_rcu(&mn->hlist); +- spin_unlock(&mm->mmu_notifier_mm->lock); +- + if (mn->ops->release) + mn->ops->release(mn, mm); ++ srcu_read_unlock(&srcu, id); + ++ spin_lock(&mm->mmu_notifier_mm->lock); + /* +- * Allow __mmu_notifier_release() to complete. ++ * Can not use list_del_rcu() since __mmu_notifier_release ++ * can delete it before we hold the lock. + */ +- srcu_read_unlock(&srcu, id); +- } else ++ hlist_del_init_rcu(&mn->hlist); + spin_unlock(&mm->mmu_notifier_mm->lock); ++ } + + /* +- * Wait for any running method to finish, including ->release() if it +- * was run by __mmu_notifier_release() instead of us. ++ * Wait for any running method to finish, of course including ++ * ->release if it was run by mmu_notifier_relase instead of us. + */ + synchronize_srcu(&srcu); + +diff --git a/mm/pagewalk.c b/mm/pagewalk.c +index aa9701e..1090e77 100644 +--- a/mm/pagewalk.c ++++ b/mm/pagewalk.c +@@ -127,28 +127,7 @@ static int walk_hugetlb_range(struct vm_area_struct *vma, + return 0; + } + +-static struct vm_area_struct* hugetlb_vma(unsigned long addr, struct mm_walk *walk) +-{ +- struct vm_area_struct *vma; +- +- /* We don't need vma lookup at all. */ +- if (!walk->hugetlb_entry) +- return NULL; +- +- VM_BUG_ON(!rwsem_is_locked(&walk->mm->mmap_sem)); +- vma = find_vma(walk->mm, addr); +- if (vma && vma->vm_start <= addr && is_vm_hugetlb_page(vma)) +- return vma; +- +- return NULL; +-} +- + #else /* CONFIG_HUGETLB_PAGE */ +-static struct vm_area_struct* hugetlb_vma(unsigned long addr, struct mm_walk *walk) +-{ +- return NULL; +-} +- + static int walk_hugetlb_range(struct vm_area_struct *vma, + unsigned long addr, unsigned long end, + struct mm_walk *walk) +@@ -199,30 +178,53 @@ int walk_page_range(unsigned long addr, unsigned long end, + if (!walk->mm) + return -EINVAL; + ++ VM_BUG_ON(!rwsem_is_locked(&walk->mm->mmap_sem)); ++ + pgd = pgd_offset(walk->mm, addr); + do { +- struct vm_area_struct *vma; ++ struct vm_area_struct *vma = NULL; + + next = pgd_addr_end(addr, end); + + /* +- * handle hugetlb vma individually because pagetable walk for +- * the hugetlb page is dependent on the architecture and +- * we can't handled it in the same manner as non-huge pages. ++ * This function was not intended to be vma based. ++ * But there are vma special cases to be handled: ++ * - hugetlb vma's ++ * - VM_PFNMAP vma's + */ +- vma = hugetlb_vma(addr, walk); ++ vma = find_vma(walk->mm, addr); + if (vma) { +- if (vma->vm_end < next) ++ /* ++ * There are no page structures backing a VM_PFNMAP ++ * range, so do not allow split_huge_page_pmd(). ++ */ ++ if ((vma->vm_start <= addr) && ++ (vma->vm_flags & VM_PFNMAP)) { + next = vma->vm_end; ++ pgd = pgd_offset(walk->mm, next); ++ continue; ++ } + /* +- * Hugepage is very tightly coupled with vma, so +- * walk through hugetlb entries within a given vma. ++ * Handle hugetlb vma individually because pagetable ++ * walk for the hugetlb page is dependent on the ++ * architecture and we can't handled it in the same ++ * manner as non-huge pages. + */ +- err = walk_hugetlb_range(vma, addr, next, walk); +- if (err) +- break; +- pgd = pgd_offset(walk->mm, next); +- continue; ++ if (walk->hugetlb_entry && (vma->vm_start <= addr) && ++ is_vm_hugetlb_page(vma)) { ++ if (vma->vm_end < next) ++ next = vma->vm_end; ++ /* ++ * Hugepage is very tightly coupled with vma, ++ * so walk through hugetlb entries within a ++ * given vma. ++ */ ++ err = walk_hugetlb_range(vma, addr, next, walk); ++ if (err) ++ break; ++ pgd = pgd_offset(walk->mm, next); ++ continue; ++ } + } + + if (pgd_none_or_clear_bad(pgd)) { +diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c +index 48f937e..95a04f0 100644 +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -1257,6 +1257,15 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local) + + ASSERT_RTNL(); + ++ /* ++ * Close all AP_VLAN interfaces first, as otherwise they ++ * might be closed while the AP interface they belong to ++ * is closed, causing unregister_netdevice_many() to crash. ++ */ ++ list_for_each_entry(sdata, &local->interfaces, list) ++ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) ++ dev_close(sdata->dev); ++ + mutex_lock(&local->iflist_mtx); + list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { + list_del(&sdata->list); +diff --git a/tools/perf/scripts/python/net_dropmonitor.py b/tools/perf/scripts/python/net_dropmonitor.py +index a4ffc95..4c11605 100755 +--- a/tools/perf/scripts/python/net_dropmonitor.py ++++ b/tools/perf/scripts/python/net_dropmonitor.py +@@ -40,9 +40,9 @@ def get_kallsyms_table(): + + def get_sym(sloc): + loc = int(sloc) +- for i in kallsyms: +- if (i['loc'] >= loc): +- return (i['name'], i['loc']-loc) ++ for i in kallsyms[::-1]: ++ if loc >= i['loc']: ++ return (i['name'], loc - i['loc']) + return (None, 0) + + def print_drop_table(): +@@ -64,7 +64,7 @@ def trace_end(): + + # called from perf, when it finds a correspoinding event + def skb__kfree_skb(name, context, cpu, sec, nsec, pid, comm, +- skbaddr, protocol, location): ++ skbaddr, location, protocol): + slocation = str(location) + try: + drop_log[slocation] = drop_log[slocation] + 1 diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.48-49.patch b/patch/kernel/sun8i-default/0001-patch-3.4.48-49.patch new file mode 100644 index 000000000..1a1786dc2 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.48-49.patch @@ -0,0 +1,1190 @@ +diff --git a/Makefile b/Makefile +index 65c0d7f..a36dada 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 48 ++SUBLEVEL = 49 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c +index 8752f79..8a811d9 100644 +--- a/arch/powerpc/platforms/pseries/eeh_pseries.c ++++ b/arch/powerpc/platforms/pseries/eeh_pseries.c +@@ -83,7 +83,11 @@ static int pseries_eeh_init(void) + ibm_configure_pe = rtas_token("ibm,configure-pe"); + ibm_configure_bridge = rtas_token ("ibm,configure-bridge"); + +- /* necessary sanity check */ ++ /* ++ * Necessary sanity check. We needn't check "get-config-addr-info" ++ * and its variant since the old firmware probably support address ++ * of domain/bus/slot/function for EEH RTAS operations. ++ */ + if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE) { + pr_warning("%s: RTAS service invalid\n", + __func__); +@@ -102,12 +106,6 @@ static int pseries_eeh_init(void) + pr_warning("%s: RTAS service invalid\n", + __func__); + return -EINVAL; +- } else if (ibm_get_config_addr_info2 == RTAS_UNKNOWN_SERVICE && +- ibm_get_config_addr_info == RTAS_UNKNOWN_SERVICE) { +- pr_warning("%s: RTAS service and " +- " invalid\n", +- __func__); +- return -EINVAL; + } else if (ibm_configure_pe == RTAS_UNKNOWN_SERVICE && + ibm_configure_bridge == RTAS_UNKNOWN_SERVICE) { + pr_warning("%s: RTAS service and " +diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c +index 91357e1..6d2c49b 100644 +--- a/drivers/acpi/video.c ++++ b/drivers/acpi/video.c +@@ -447,6 +447,22 @@ static struct dmi_system_id video_dmi_table[] __initdata = { + DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13 - 2000 Notebook PC"), + }, + }, ++ { ++ .callback = video_ignore_initial_backlight, ++ .ident = "HP Pavilion g6 Notebook PC", ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion g6 Notebook PC"), ++ }, ++ }, ++ { ++ .callback = video_ignore_initial_backlight, ++ .ident = "HP Pavilion m4", ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion m4 Notebook PC"), ++ }, ++ }, + {} + }; + +diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c +index c869436..dc33ba5 100644 +--- a/drivers/gpu/drm/drm_irq.c ++++ b/drivers/gpu/drm/drm_irq.c +@@ -981,7 +981,7 @@ EXPORT_SYMBOL(drm_vblank_off); + */ + void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) + { +- /* vblank is not initialized (IRQ not installed ?) */ ++ /* vblank is not initialized (IRQ not installed ?), or has been freed */ + if (!dev->num_crtcs) + return; + /* +@@ -1003,6 +1003,10 @@ void drm_vblank_post_modeset(struct drm_device *dev, int crtc) + { + unsigned long irqflags; + ++ /* vblank is not initialized (IRQ not installed ?), or has been freed */ ++ if (!dev->num_crtcs) ++ return; ++ + if (dev->vblank_inmodeset[crtc]) { + spin_lock_irqsave(&dev->vbl_lock, irqflags); + dev->vblank_disable_allowed = 1; +diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c +index 8ea202f..fa74a86 100644 +--- a/drivers/gpu/drm/gma500/framebuffer.c ++++ b/drivers/gpu/drm/gma500/framebuffer.c +@@ -782,8 +782,8 @@ void psb_modeset_init(struct drm_device *dev) + for (i = 0; i < dev_priv->num_pipe; i++) + psb_intel_crtc_init(dev, i, mode_dev); + +- dev->mode_config.max_width = 2048; +- dev->mode_config.max_height = 2048; ++ dev->mode_config.max_width = 4096; ++ dev->mode_config.max_height = 4096; + + psb_setup_outputs(dev); + } +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index 1ad5906..207180d 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -747,10 +747,10 @@ static const struct dmi_system_id intel_no_lvds[] = { + }, + { + .callback = intel_no_lvds_dmi_callback, +- .ident = "Hewlett-Packard HP t5740e Thin Client", ++ .ident = "Hewlett-Packard HP t5740", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), +- DMI_MATCH(DMI_PRODUCT_NAME, "HP t5740e Thin Client"), ++ DMI_MATCH(DMI_PRODUCT_NAME, " t5740"), + }, + }, + { +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index 1b6b157..aeb9d6e 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -1581,7 +1581,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) + * Assume that the preferred modes are + * arranged in priority order. + */ +- intel_ddc_get_modes(connector, intel_sdvo->i2c); ++ intel_ddc_get_modes(connector, &intel_sdvo->ddc); + if (list_empty(&connector->probed_modes) == false) + goto end; + +diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c +index 23e3ea6..ced9370 100644 +--- a/drivers/gpu/drm/radeon/atombios_encoders.c ++++ b/drivers/gpu/drm/radeon/atombios_encoders.c +@@ -396,6 +396,8 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) + int + atombios_get_encoder_mode(struct drm_encoder *encoder) + { ++ struct drm_device *dev = encoder->dev; ++ struct radeon_device *rdev = dev->dev_private; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct drm_connector *connector; + struct radeon_connector *radeon_connector; +@@ -421,7 +423,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) + case DRM_MODE_CONNECTOR_DVII: + case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ + if (drm_detect_hdmi_monitor(radeon_connector->edid) && +- radeon_audio) ++ radeon_audio && ++ !ASIC_IS_DCE6(rdev)) /* remove once we support DCE6 */ + return ATOM_ENCODER_MODE_HDMI; + else if (radeon_connector->use_digital) + return ATOM_ENCODER_MODE_DVI; +@@ -432,7 +435,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) + case DRM_MODE_CONNECTOR_HDMIA: + default: + if (drm_detect_hdmi_monitor(radeon_connector->edid) && +- radeon_audio) ++ radeon_audio && ++ !ASIC_IS_DCE6(rdev)) /* remove once we support DCE6 */ + return ATOM_ENCODER_MODE_HDMI; + else + return ATOM_ENCODER_MODE_DVI; +@@ -446,7 +450,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) + (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) + return ATOM_ENCODER_MODE_DP; + else if (drm_detect_hdmi_monitor(radeon_connector->edid) && +- radeon_audio) ++ radeon_audio && ++ !ASIC_IS_DCE6(rdev)) /* remove once we support DCE6 */ + return ATOM_ENCODER_MODE_HDMI; + else + return ATOM_ENCODER_MODE_DVI; +diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c +index 6a8776e..300099d 100644 +--- a/drivers/gpu/drm/radeon/evergreen.c ++++ b/drivers/gpu/drm/radeon/evergreen.c +@@ -3258,6 +3258,12 @@ static int evergreen_startup(struct radeon_device *rdev) + } + + /* Enable IRQ */ ++ if (!rdev->irq.installed) { ++ r = radeon_irq_kms_init(rdev); ++ if (r) ++ return r; ++ } ++ + r = r600_irq_init(rdev); + if (r) { + DRM_ERROR("radeon: IH init failed (%d).\n", r); +@@ -3409,10 +3415,6 @@ int evergreen_init(struct radeon_device *rdev) + if (r) + return r; + +- r = radeon_irq_kms_init(rdev); +- if (r) +- return r; +- + rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; + r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024); + +diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c +index d706da8..f5387b3 100644 +--- a/drivers/gpu/drm/radeon/ni.c ++++ b/drivers/gpu/drm/radeon/ni.c +@@ -1614,6 +1614,12 @@ static int cayman_startup(struct radeon_device *rdev) + } + + /* Enable IRQ */ ++ if (!rdev->irq.installed) { ++ r = radeon_irq_kms_init(rdev); ++ if (r) ++ return r; ++ } ++ + r = r600_irq_init(rdev); + if (r) { + DRM_ERROR("radeon: IH init failed (%d).\n", r); +@@ -1744,10 +1750,6 @@ int cayman_init(struct radeon_device *rdev) + if (r) + return r; + +- r = radeon_irq_kms_init(rdev); +- if (r) +- return r; +- + ring->ring_obj = NULL; + r600_ring_init(rdev, ring, 1024 * 1024); + +diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c +index fe33d35..40ed0e5 100644 +--- a/drivers/gpu/drm/radeon/r100.c ++++ b/drivers/gpu/drm/radeon/r100.c +@@ -3952,6 +3952,12 @@ static int r100_startup(struct radeon_device *rdev) + } + + /* Enable IRQ */ ++ if (!rdev->irq.installed) { ++ r = radeon_irq_kms_init(rdev); ++ if (r) ++ return r; ++ } ++ + r100_irq_set(rdev); + rdev->config.r100.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); + /* 1M ring buffer */ +@@ -4113,9 +4119,6 @@ int r100_init(struct radeon_device *rdev) + r = radeon_fence_driver_init(rdev); + if (r) + return r; +- r = radeon_irq_kms_init(rdev); +- if (r) +- return r; + /* Memory manager */ + r = radeon_bo_init(rdev); + if (r) +diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c +index fa14383..63b53aa 100644 +--- a/drivers/gpu/drm/radeon/r300.c ++++ b/drivers/gpu/drm/radeon/r300.c +@@ -1405,6 +1405,12 @@ static int r300_startup(struct radeon_device *rdev) + } + + /* Enable IRQ */ ++ if (!rdev->irq.installed) { ++ r = radeon_irq_kms_init(rdev); ++ if (r) ++ return r; ++ } ++ + r100_irq_set(rdev); + rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); + /* 1M ring buffer */ +@@ -1545,9 +1551,6 @@ int r300_init(struct radeon_device *rdev) + r = radeon_fence_driver_init(rdev); + if (r) + return r; +- r = radeon_irq_kms_init(rdev); +- if (r) +- return r; + /* Memory manager */ + r = radeon_bo_init(rdev); + if (r) +diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c +index f3fcaac..1a9347f 100644 +--- a/drivers/gpu/drm/radeon/r420.c ++++ b/drivers/gpu/drm/radeon/r420.c +@@ -265,6 +265,12 @@ static int r420_startup(struct radeon_device *rdev) + } + + /* Enable IRQ */ ++ if (!rdev->irq.installed) { ++ r = radeon_irq_kms_init(rdev); ++ if (r) ++ return r; ++ } ++ + r100_irq_set(rdev); + rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); + /* 1M ring buffer */ +@@ -417,10 +423,6 @@ int r420_init(struct radeon_device *rdev) + if (r) { + return r; + } +- r = radeon_irq_kms_init(rdev); +- if (r) { +- return r; +- } + /* Memory manager */ + r = radeon_bo_init(rdev); + if (r) { +diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c +index ebcc15b..57be784 100644 +--- a/drivers/gpu/drm/radeon/r520.c ++++ b/drivers/gpu/drm/radeon/r520.c +@@ -194,6 +194,12 @@ static int r520_startup(struct radeon_device *rdev) + } + + /* Enable IRQ */ ++ if (!rdev->irq.installed) { ++ r = radeon_irq_kms_init(rdev); ++ if (r) ++ return r; ++ } ++ + rs600_irq_set(rdev); + rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); + /* 1M ring buffer */ +@@ -301,9 +307,6 @@ int r520_init(struct radeon_device *rdev) + r = radeon_fence_driver_init(rdev); + if (r) + return r; +- r = radeon_irq_kms_init(rdev); +- if (r) +- return r; + /* Memory manager */ + r = radeon_bo_init(rdev); + if (r) +diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c +index b1ff9cc..8c403d9 100644 +--- a/drivers/gpu/drm/radeon/r600.c ++++ b/drivers/gpu/drm/radeon/r600.c +@@ -2470,6 +2470,12 @@ int r600_startup(struct radeon_device *rdev) + } + + /* Enable IRQ */ ++ if (!rdev->irq.installed) { ++ r = radeon_irq_kms_init(rdev); ++ if (r) ++ return r; ++ } ++ + r = r600_irq_init(rdev); + if (r) { + DRM_ERROR("radeon: IH init failed (%d).\n", r); +@@ -2624,10 +2630,6 @@ int r600_init(struct radeon_device *rdev) + if (r) + return r; + +- r = radeon_irq_kms_init(rdev); +- if (r) +- return r; +- + rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; + r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024); + +diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c +index 4cf381b..5099bd3 100644 +--- a/drivers/gpu/drm/radeon/rs400.c ++++ b/drivers/gpu/drm/radeon/rs400.c +@@ -417,6 +417,12 @@ static int rs400_startup(struct radeon_device *rdev) + } + + /* Enable IRQ */ ++ if (!rdev->irq.installed) { ++ r = radeon_irq_kms_init(rdev); ++ if (r) ++ return r; ++ } ++ + r100_irq_set(rdev); + rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); + /* 1M ring buffer */ +@@ -541,9 +547,6 @@ int rs400_init(struct radeon_device *rdev) + r = radeon_fence_driver_init(rdev); + if (r) + return r; +- r = radeon_irq_kms_init(rdev); +- if (r) +- return r; + /* Memory manager */ + r = radeon_bo_init(rdev); + if (r) +diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c +index d25cf86..5248001 100644 +--- a/drivers/gpu/drm/radeon/rs600.c ++++ b/drivers/gpu/drm/radeon/rs600.c +@@ -864,6 +864,12 @@ static int rs600_startup(struct radeon_device *rdev) + } + + /* Enable IRQ */ ++ if (!rdev->irq.installed) { ++ r = radeon_irq_kms_init(rdev); ++ if (r) ++ return r; ++ } ++ + rs600_irq_set(rdev); + rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); + /* 1M ring buffer */ +@@ -994,9 +1000,6 @@ int rs600_init(struct radeon_device *rdev) + r = radeon_fence_driver_init(rdev); + if (r) + return r; +- r = radeon_irq_kms_init(rdev); +- if (r) +- return r; + /* Memory manager */ + r = radeon_bo_init(rdev); + if (r) +diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c +index f2c3b9d..c46900c 100644 +--- a/drivers/gpu/drm/radeon/rs690.c ++++ b/drivers/gpu/drm/radeon/rs690.c +@@ -628,6 +628,12 @@ static int rs690_startup(struct radeon_device *rdev) + } + + /* Enable IRQ */ ++ if (!rdev->irq.installed) { ++ r = radeon_irq_kms_init(rdev); ++ if (r) ++ return r; ++ } ++ + rs600_irq_set(rdev); + rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); + /* 1M ring buffer */ +@@ -759,9 +765,6 @@ int rs690_init(struct radeon_device *rdev) + r = radeon_fence_driver_init(rdev); + if (r) + return r; +- r = radeon_irq_kms_init(rdev); +- if (r) +- return r; + /* Memory manager */ + r = radeon_bo_init(rdev); + if (r) +diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c +index 43af363..0532bbe 100644 +--- a/drivers/gpu/drm/radeon/rv515.c ++++ b/drivers/gpu/drm/radeon/rv515.c +@@ -386,6 +386,12 @@ static int rv515_startup(struct radeon_device *rdev) + } + + /* Enable IRQ */ ++ if (!rdev->irq.installed) { ++ r = radeon_irq_kms_init(rdev); ++ if (r) ++ return r; ++ } ++ + rs600_irq_set(rdev); + rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); + /* 1M ring buffer */ +@@ -520,9 +526,6 @@ int rv515_init(struct radeon_device *rdev) + r = radeon_fence_driver_init(rdev); + if (r) + return r; +- r = radeon_irq_kms_init(rdev); +- if (r) +- return r; + /* Memory manager */ + r = radeon_bo_init(rdev); + if (r) +diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c +index 591040b..4a3937f 100644 +--- a/drivers/gpu/drm/radeon/rv770.c ++++ b/drivers/gpu/drm/radeon/rv770.c +@@ -1099,6 +1099,12 @@ static int rv770_startup(struct radeon_device *rdev) + } + + /* Enable IRQ */ ++ if (!rdev->irq.installed) { ++ r = radeon_irq_kms_init(rdev); ++ if (r) ++ return r; ++ } ++ + r = r600_irq_init(rdev); + if (r) { + DRM_ERROR("radeon: IH init failed (%d).\n", r); +@@ -1237,10 +1243,6 @@ int rv770_init(struct radeon_device *rdev) + if (r) + return r; + +- r = radeon_irq_kms_init(rdev); +- if (r) +- return r; +- + rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; + r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024); + +diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c +index 2dbd585..e22b460 100644 +--- a/drivers/gpu/drm/radeon/si.c ++++ b/drivers/gpu/drm/radeon/si.c +@@ -3876,6 +3876,12 @@ static int si_startup(struct radeon_device *rdev) + } + + /* Enable IRQ */ ++ if (!rdev->irq.installed) { ++ r = radeon_irq_kms_init(rdev); ++ if (r) ++ return r; ++ } ++ + r = si_irq_init(rdev); + if (r) { + DRM_ERROR("radeon: IH init failed (%d).\n", r); +@@ -4044,10 +4050,6 @@ int si_init(struct radeon_device *rdev) + if (r) + return r; + +- r = radeon_irq_kms_init(rdev); +- if (r) +- return r; +- + ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; + ring->ring_obj = NULL; + r600_ring_init(rdev, ring, 1024 * 1024); +diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c +index 4394e7e..5653461 100644 +--- a/drivers/hwmon/adm1021.c ++++ b/drivers/hwmon/adm1021.c +@@ -332,26 +332,68 @@ static int adm1021_detect(struct i2c_client *client, + man_id = i2c_smbus_read_byte_data(client, ADM1021_REG_MAN_ID); + dev_id = i2c_smbus_read_byte_data(client, ADM1021_REG_DEV_ID); + ++ if (man_id < 0 || dev_id < 0) ++ return -ENODEV; ++ + if (man_id == 0x4d && dev_id == 0x01) + type_name = "max1617a"; + else if (man_id == 0x41) { + if ((dev_id & 0xF0) == 0x30) + type_name = "adm1023"; +- else ++ else if ((dev_id & 0xF0) == 0x00) + type_name = "adm1021"; ++ else ++ return -ENODEV; + } else if (man_id == 0x49) + type_name = "thmc10"; + else if (man_id == 0x23) + type_name = "gl523sm"; + else if (man_id == 0x54) + type_name = "mc1066"; +- /* LM84 Mfr ID in a different place, and it has more unused bits */ +- else if (conv_rate == 0x00 +- && (config & 0x7F) == 0x00 +- && (status & 0xAB) == 0x00) +- type_name = "lm84"; +- else +- type_name = "max1617"; ++ else { ++ int lte, rte, lhi, rhi, llo, rlo; ++ ++ /* extra checks for LM84 and MAX1617 to avoid misdetections */ ++ ++ llo = i2c_smbus_read_byte_data(client, ADM1021_REG_THYST_R(0)); ++ rlo = i2c_smbus_read_byte_data(client, ADM1021_REG_THYST_R(1)); ++ ++ /* fail if any of the additional register reads failed */ ++ if (llo < 0 || rlo < 0) ++ return -ENODEV; ++ ++ lte = i2c_smbus_read_byte_data(client, ADM1021_REG_TEMP(0)); ++ rte = i2c_smbus_read_byte_data(client, ADM1021_REG_TEMP(1)); ++ lhi = i2c_smbus_read_byte_data(client, ADM1021_REG_TOS_R(0)); ++ rhi = i2c_smbus_read_byte_data(client, ADM1021_REG_TOS_R(1)); ++ ++ /* ++ * Fail for negative temperatures and negative high limits. ++ * This check also catches read errors on the tested registers. ++ */ ++ if ((s8)lte < 0 || (s8)rte < 0 || (s8)lhi < 0 || (s8)rhi < 0) ++ return -ENODEV; ++ ++ /* fail if all registers hold the same value */ ++ if (lte == rte && lte == lhi && lte == rhi && lte == llo ++ && lte == rlo) ++ return -ENODEV; ++ ++ /* ++ * LM84 Mfr ID is in a different place, ++ * and it has more unused bits. ++ */ ++ if (conv_rate == 0x00 ++ && (config & 0x7F) == 0x00 ++ && (status & 0xAB) == 0x00) { ++ type_name = "lm84"; ++ } else { ++ /* fail if low limits are larger than high limits */ ++ if ((s8)llo > lhi || (s8)rlo > rhi) ++ return -ENODEV; ++ type_name = "max1617"; ++ } ++ } + + pr_debug("adm1021: Detected chip %s at adapter %d, address 0x%02x.\n", + type_name, i2c_adapter_id(adapter), client->addr); +diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c +index 14d2d71..a60679c 100644 +--- a/drivers/usb/host/ehci-sched.c ++++ b/drivers/usb/host/ehci-sched.c +@@ -236,7 +236,7 @@ static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __hc32 mask) + } + + static const unsigned char +-max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 125, 25 }; ++max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 }; + + /* carryover low/fullspeed bandwidth that crosses uframe boundries */ + static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8]) +diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c +index f059222..5080b1d 100644 +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -1845,6 +1845,9 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) + } + spin_unlock_irqrestore(&xhci->lock, flags); + ++ if (!xhci->rh_bw) ++ goto no_bw; ++ + num_ports = HCS_MAX_PORTS(xhci->hcs_params1); + for (i = 0; i < num_ports; i++) { + struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table; +@@ -1863,6 +1866,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) + } + } + ++no_bw: + xhci->num_usb2_ports = 0; + xhci->num_usb3_ports = 0; + xhci->num_active_eps = 0; +@@ -2274,6 +2278,9 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) + u32 page_size, temp; + int i; + ++ INIT_LIST_HEAD(&xhci->lpm_failed_devs); ++ INIT_LIST_HEAD(&xhci->cancel_cmd_list); ++ + page_size = xhci_readl(xhci, &xhci->op_regs->page_size); + xhci_dbg(xhci, "Supported page size register = 0x%x\n", page_size); + for (i = 0; i < 16; i++) { +@@ -2352,7 +2359,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) + xhci->cmd_ring = xhci_ring_alloc(xhci, 1, 1, TYPE_COMMAND, flags); + if (!xhci->cmd_ring) + goto fail; +- INIT_LIST_HEAD(&xhci->cancel_cmd_list); + xhci_dbg(xhci, "Allocated command ring at %p\n", xhci->cmd_ring); + xhci_dbg(xhci, "First segment DMA is 0x%llx\n", + (unsigned long long)xhci->cmd_ring->first_seg->dma); +@@ -2453,8 +2459,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) + if (xhci_setup_port_arrays(xhci, flags)) + goto fail; + +- INIT_LIST_HEAD(&xhci->lpm_failed_devs); +- + /* Enable USB 3.0 device notifications for function remote wake, which + * is necessary for allowing USB 3.0 devices to do remote wakeup from + * U3 (device suspend). +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index ec2c89f..0f928b3 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -947,6 +947,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) + struct usb_hcd *hcd = xhci_to_hcd(xhci); + struct usb_hcd *secondary_hcd; + int retval = 0; ++ bool comp_timer_running = false; + + /* Wait a bit if either of the roothubs need to settle from the + * transition into bus suspend. +@@ -984,6 +985,13 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) + + /* If restore operation fails, re-initialize the HC during resume */ + if ((temp & STS_SRE) || hibernated) { ++ ++ if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && ++ !(xhci_all_ports_seen_u0(xhci))) { ++ del_timer_sync(&xhci->comp_mode_recovery_timer); ++ xhci_dbg(xhci, "Compliance Mode Recovery Timer deleted!\n"); ++ } ++ + /* Let the USB core know _both_ roothubs lost power. */ + usb_root_hub_lost_power(xhci->main_hcd->self.root_hub); + usb_root_hub_lost_power(xhci->shared_hcd->self.root_hub); +@@ -1026,6 +1034,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) + retval = xhci_init(hcd->primary_hcd); + if (retval) + return retval; ++ comp_timer_running = true; ++ + xhci_dbg(xhci, "Start the primary HCD\n"); + retval = xhci_run(hcd->primary_hcd); + if (!retval) { +@@ -1067,7 +1077,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) + * to suffer the Compliance Mode issue again. It doesn't matter if + * ports have entered previously to U0 before system's suspension. + */ +- if (xhci->quirks & XHCI_COMP_MODE_QUIRK) ++ if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && !comp_timer_running) + compliance_mode_recovery_timer_init(xhci); + + /* Re-enable port polling. */ +diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c +index f99f471..31bfe60 100644 +--- a/drivers/usb/serial/ark3116.c ++++ b/drivers/usb/serial/ark3116.c +@@ -49,7 +49,7 @@ static bool debug; + #define DRIVER_NAME "ark3116" + + /* usb timeout of 1 second */ +-#define ARK_TIMEOUT (1*HZ) ++#define ARK_TIMEOUT 1000 + + static const struct usb_device_id id_table[] = { + { USB_DEVICE(0x6547, 0x0232) }, +diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c +index afc886c..270bda8 100644 +--- a/drivers/usb/serial/cypress_m8.c ++++ b/drivers/usb/serial/cypress_m8.c +@@ -70,6 +70,7 @@ static const struct usb_device_id id_table_earthmate[] = { + static const struct usb_device_id id_table_cyphidcomrs232[] = { + { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, + { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) }, ++ { USB_DEVICE(VENDOR_ID_FRWD, PRODUCT_ID_CYPHIDCOM_FRWD) }, + { } /* Terminating entry */ + }; + +@@ -83,6 +84,7 @@ static const struct usb_device_id id_table_combined[] = { + { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) }, + { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, + { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) }, ++ { USB_DEVICE(VENDOR_ID_FRWD, PRODUCT_ID_CYPHIDCOM_FRWD) }, + { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) }, + { } /* Terminating entry */ + }; +@@ -243,6 +245,12 @@ static struct usb_serial_driver * const serial_drivers[] = { + * Cypress serial helper functions + *****************************************************************************/ + ++/* FRWD Dongle hidcom needs to skip reset and speed checks */ ++static inline bool is_frwd(struct usb_device *dev) ++{ ++ return ((le16_to_cpu(dev->descriptor.idVendor) == VENDOR_ID_FRWD) && ++ (le16_to_cpu(dev->descriptor.idProduct) == PRODUCT_ID_CYPHIDCOM_FRWD)); ++} + + static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate) + { +@@ -252,6 +260,10 @@ static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate) + if (unstable_bauds) + return new_rate; + ++ /* FRWD Dongle uses 115200 bps */ ++ if (is_frwd(port->serial->dev)) ++ return new_rate; ++ + /* + * The general purpose firmware for the Cypress M8 allows for + * a maximum speed of 57600bps (I have no idea whether DeLorme +@@ -465,7 +477,11 @@ static int generic_startup(struct usb_serial *serial) + } + init_waitqueue_head(&priv->delta_msr_wait); + +- usb_reset_configuration(serial->dev); ++ /* Skip reset for FRWD device. It is a workaound: ++ device hangs if it receives SET_CONFIGURE in Configured ++ state. */ ++ if (!is_frwd(serial->dev)) ++ usb_reset_configuration(serial->dev); + + priv->cmd_ctrl = 0; + priv->line_control = 0; +diff --git a/drivers/usb/serial/cypress_m8.h b/drivers/usb/serial/cypress_m8.h +index 67cf608..b461311 100644 +--- a/drivers/usb/serial/cypress_m8.h ++++ b/drivers/usb/serial/cypress_m8.h +@@ -24,6 +24,10 @@ + #define VENDOR_ID_CYPRESS 0x04b4 + #define PRODUCT_ID_CYPHIDCOM 0x5500 + ++/* FRWD Dongle - a GPS sports watch */ ++#define VENDOR_ID_FRWD 0x6737 ++#define PRODUCT_ID_CYPHIDCOM_FRWD 0x0001 ++ + /* Powercom UPS, chip CY7C63723 */ + #define VENDOR_ID_POWERCOM 0x0d9f + #define PRODUCT_ID_UPS 0x0002 +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index c6f8e62..f8a9cd7 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -2173,7 +2173,7 @@ static void ftdi_set_termios(struct tty_struct *tty, + + cflag = termios->c_cflag; + +- if (old_termios == 0) ++ if (!old_termios) + goto no_skip; + + if (old_termios->c_cflag == termios->c_cflag +diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c +index f2192d5..53c639c 100644 +--- a/drivers/usb/serial/iuu_phoenix.c ++++ b/drivers/usb/serial/iuu_phoenix.c +@@ -326,7 +326,7 @@ static int bulk_immediate(struct usb_serial_port *port, u8 *buf, u8 count) + usb_bulk_msg(serial->dev, + usb_sndbulkpipe(serial->dev, + port->bulk_out_endpointAddress), buf, +- count, &actual, HZ * 1); ++ count, &actual, 1000); + + if (status != IUU_OPERATION_OK) + dbg("%s - error = %2x", __func__, status); +@@ -349,7 +349,7 @@ static int read_immediate(struct usb_serial_port *port, u8 *buf, u8 count) + usb_bulk_msg(serial->dev, + usb_rcvbulkpipe(serial->dev, + port->bulk_in_endpointAddress), buf, +- count, &actual, HZ * 1); ++ count, &actual, 1000); + + if (status != IUU_OPERATION_OK) + dbg("%s - error = %2x", __func__, status); +diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c +index a39ddd1..253bff6 100644 +--- a/drivers/usb/serial/keyspan.c ++++ b/drivers/usb/serial/keyspan.c +@@ -1705,7 +1705,7 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial, + d_details = s_priv->device_details; + device_port = port->number - port->serial->minor; + +- outcont_urb = d_details->outcont_endpoints[port->number]; ++ outcont_urb = d_details->outcont_endpoints[device_port]; + this_urb = p_priv->outcont_urb; + + dbg("%s - endpoint %d", __func__, usb_pipeendpoint(this_urb->pipe)); +diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c +index bdce820..77d974d 100644 +--- a/drivers/usb/serial/mos7720.c ++++ b/drivers/usb/serial/mos7720.c +@@ -44,7 +44,7 @@ + #define DRIVER_DESC "Moschip USB Serial Driver" + + /* default urb timeout */ +-#define MOS_WDR_TIMEOUT (HZ * 5) ++#define MOS_WDR_TIMEOUT 5000 + + #define MOS_MAX_PORT 0x02 + #define MOS_WRITE 0x0E +@@ -234,11 +234,22 @@ static int read_mos_reg(struct usb_serial *serial, unsigned int serial_portnum, + __u8 requesttype = (__u8)0xc0; + __u16 index = get_reg_index(reg); + __u16 value = get_reg_value(reg, serial_portnum); +- int status = usb_control_msg(usbdev, pipe, request, requesttype, value, +- index, data, 1, MOS_WDR_TIMEOUT); +- if (status < 0) ++ u8 *buf; ++ int status; ++ ++ buf = kmalloc(1, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ status = usb_control_msg(usbdev, pipe, request, requesttype, value, ++ index, buf, 1, MOS_WDR_TIMEOUT); ++ if (status == 1) ++ *data = *buf; ++ else if (status < 0) + dev_err(&usbdev->dev, + "mos7720: usb_control_msg() failed: %d", status); ++ kfree(buf); ++ + return status; + } + +@@ -1690,7 +1701,7 @@ static void change_port_settings(struct tty_struct *tty, + mos7720_port->shadowMCR |= (UART_MCR_XONANY); + /* To set hardware flow control to the specified * + * serial port, in SP1/2_CONTROL_REG */ +- if (port->number) ++ if (port_number) + write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x01); + else + write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x02); +@@ -2094,7 +2105,7 @@ static int mos7720_startup(struct usb_serial *serial) + + /* setting configuration feature to one */ + usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), +- (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ); ++ (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5000); + + /* start the interrupt urb */ + ret_val = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL); +@@ -2139,7 +2150,7 @@ static void mos7720_release(struct usb_serial *serial) + /* wait for synchronous usb calls to return */ + if (mos_parport->msg_pending) + wait_for_completion_timeout(&mos_parport->syncmsg_compl, +- MOS_WDR_TIMEOUT); ++ msecs_to_jiffies(MOS_WDR_TIMEOUT)); + + parport_remove_port(mos_parport->pp); + usb_set_serial_data(serial, NULL); +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 386b3ab..5b24260 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -593,6 +593,8 @@ static const struct usb_device_id option_ids[] = { + .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x14ac, 0xff, 0xff, 0xff), /* Huawei E1820 */ ++ .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0xff, 0xff) }, +diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c +index 71d6964..b3afd19 100644 +--- a/drivers/usb/serial/visor.c ++++ b/drivers/usb/serial/visor.c +@@ -596,10 +596,19 @@ static int treo_attach(struct usb_serial *serial) + */ + #define COPY_PORT(dest, src) \ + do { \ ++ int i; \ ++ \ ++ for (i = 0; i < ARRAY_SIZE(src->read_urbs); ++i) { \ ++ dest->read_urbs[i] = src->read_urbs[i]; \ ++ dest->read_urbs[i]->context = dest; \ ++ dest->bulk_in_buffers[i] = src->bulk_in_buffers[i]; \ ++ } \ + dest->read_urb = src->read_urb; \ + dest->bulk_in_endpointAddress = src->bulk_in_endpointAddress;\ + dest->bulk_in_buffer = src->bulk_in_buffer; \ ++ dest->bulk_in_size = src->bulk_in_size; \ + dest->interrupt_in_urb = src->interrupt_in_urb; \ ++ dest->interrupt_in_urb->context = dest; \ + dest->interrupt_in_endpointAddress = \ + src->interrupt_in_endpointAddress;\ + dest->interrupt_in_buffer = src->interrupt_in_buffer; \ +diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c +index 171226a..0d06d7c 100644 +--- a/drivers/usb/serial/whiteheat.c ++++ b/drivers/usb/serial/whiteheat.c +@@ -1154,7 +1154,7 @@ static void firm_setup_port(struct tty_struct *tty) + struct whiteheat_port_settings port_settings; + unsigned int cflag = tty->termios->c_cflag; + +- port_settings.port = port->number + 1; ++ port_settings.port = port->number - port->serial->minor + 1; + + /* get the byte size */ + switch (cflag & CSIZE) { +diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c +index b6df20a..d52703c 100644 +--- a/drivers/xen/xen-pciback/pciback_ops.c ++++ b/drivers/xen/xen-pciback/pciback_ops.c +@@ -9,6 +9,8 @@ + #include + #include + #include "pciback.h" ++#include ++#include + + int verbose_request; + module_param(verbose_request, int, 0644); +@@ -136,7 +138,6 @@ int xen_pcibk_enable_msi(struct xen_pcibk_device *pdev, + struct pci_dev *dev, struct xen_pci_op *op) + { + struct xen_pcibk_dev_data *dev_data; +- int otherend = pdev->xdev->otherend_id; + int status; + + if (unlikely(verbose_request)) +@@ -145,8 +146,9 @@ int xen_pcibk_enable_msi(struct xen_pcibk_device *pdev, + status = pci_enable_msi(dev); + + if (status) { +- printk(KERN_ERR "error enable msi for guest %x status %x\n", +- otherend, status); ++ pr_warn_ratelimited(DRV_NAME ": %s: error enabling MSI for guest %u: err %d\n", ++ pci_name(dev), pdev->xdev->otherend_id, ++ status); + op->value = 0; + return XEN_PCI_ERR_op_failed; + } +@@ -224,10 +226,10 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev, + pci_name(dev), i, + op->msix_entries[i].vector); + } +- } else { +- printk(KERN_WARNING DRV_NAME ": %s: failed to enable MSI-X: err %d!\n", +- pci_name(dev), result); +- } ++ } else ++ pr_warn_ratelimited(DRV_NAME ": %s: error enabling MSI-X for guest %u: err %d!\n", ++ pci_name(dev), pdev->xdev->otherend_id, ++ result); + kfree(entries); + + op->value = result; +diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h +index 72a6cab..f80ca4a 100644 +--- a/include/linux/ftrace.h ++++ b/include/linux/ftrace.h +@@ -299,7 +299,6 @@ ssize_t ftrace_filter_write(struct file *file, const char __user *ubuf, + size_t cnt, loff_t *ppos); + ssize_t ftrace_notrace_write(struct file *file, const char __user *ubuf, + size_t cnt, loff_t *ppos); +-loff_t ftrace_regex_lseek(struct file *file, loff_t offset, int origin); + int ftrace_regex_release(struct inode *inode, struct file *file); + + void __init +@@ -420,6 +419,8 @@ static inline int + ftrace_regex_release(struct inode *inode, struct file *file) { return -ENODEV; } + #endif /* CONFIG_DYNAMIC_FTRACE */ + ++loff_t ftrace_filter_lseek(struct file *file, loff_t offset, int whence); ++ + /* totally disable ftrace - can not re-enable after this */ + void ftrace_kill(void); + +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index c962d31..e101cf9 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -999,6 +999,19 @@ static __init void ftrace_profile_debugfs(struct dentry *d_tracer) + + static struct pid * const ftrace_swapper_pid = &init_struct_pid; + ++loff_t ++ftrace_filter_lseek(struct file *file, loff_t offset, int whence) ++{ ++ loff_t ret; ++ ++ if (file->f_mode & FMODE_READ) ++ ret = seq_lseek(file, offset, whence); ++ else ++ file->f_pos = ret = 1; ++ ++ return ret; ++} ++ + #ifdef CONFIG_DYNAMIC_FTRACE + + #ifndef CONFIG_FTRACE_MCOUNT_RECORD +@@ -2541,7 +2554,7 @@ static void ftrace_filter_reset(struct ftrace_hash *hash) + * routine, you can use ftrace_filter_write() for the write + * routine if @flag has FTRACE_ITER_FILTER set, or + * ftrace_notrace_write() if @flag has FTRACE_ITER_NOTRACE set. +- * ftrace_regex_lseek() should be used as the lseek routine, and ++ * ftrace_filter_lseek() should be used as the lseek routine, and + * release must call ftrace_regex_release(). + */ + int +@@ -2625,19 +2638,6 @@ ftrace_notrace_open(struct inode *inode, struct file *file) + inode, file); + } + +-loff_t +-ftrace_regex_lseek(struct file *file, loff_t offset, int origin) +-{ +- loff_t ret; +- +- if (file->f_mode & FMODE_READ) +- ret = seq_lseek(file, offset, origin); +- else +- file->f_pos = ret = 1; +- +- return ret; +-} +- + static int ftrace_match(char *str, char *regex, int len, int type) + { + int matched = 0; +@@ -3445,7 +3445,7 @@ static const struct file_operations ftrace_filter_fops = { + .open = ftrace_filter_open, + .read = seq_read, + .write = ftrace_filter_write, +- .llseek = ftrace_regex_lseek, ++ .llseek = ftrace_filter_lseek, + .release = ftrace_regex_release, + }; + +@@ -3453,7 +3453,7 @@ static const struct file_operations ftrace_notrace_fops = { + .open = ftrace_notrace_open, + .read = seq_read, + .write = ftrace_notrace_write, +- .llseek = ftrace_regex_lseek, ++ .llseek = ftrace_filter_lseek, + .release = ftrace_regex_release, + }; + +@@ -3659,8 +3659,8 @@ static const struct file_operations ftrace_graph_fops = { + .open = ftrace_graph_open, + .read = seq_read, + .write = ftrace_graph_write, ++ .llseek = ftrace_filter_lseek, + .release = ftrace_graph_release, +- .llseek = seq_lseek, + }; + #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ + +@@ -4261,7 +4261,7 @@ static const struct file_operations ftrace_pid_fops = { + .open = ftrace_pid_open, + .write = ftrace_pid_write, + .read = seq_read, +- .llseek = seq_lseek, ++ .llseek = ftrace_filter_lseek, + .release = ftrace_pid_release, + }; + +diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c +index c70f6bf..8298997 100644 +--- a/kernel/trace/trace_stack.c ++++ b/kernel/trace/trace_stack.c +@@ -384,7 +384,7 @@ static const struct file_operations stack_trace_filter_fops = { + .open = stack_trace_filter_open, + .read = seq_read, + .write = ftrace_filter_write, +- .llseek = ftrace_regex_lseek, ++ .llseek = ftrace_filter_lseek, + .release = ftrace_regex_release, + }; + +diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c +index f008fc7..e075a67 100644 +--- a/sound/usb/mixer.c ++++ b/sound/usb/mixer.c +@@ -822,6 +822,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, + case USB_ID(0x046d, 0x0808): + case USB_ID(0x046d, 0x0809): + case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */ ++ case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */ + case USB_ID(0x046d, 0x0991): + /* Most audio usb devices lie about volume resolution. + * Most Logitech webcams have res = 384. +diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h +index fa4c2f7..915bc2c 100644 +--- a/sound/usb/quirks-table.h ++++ b/sound/usb/quirks-table.h +@@ -157,7 +157,13 @@ + .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL + }, + { +- USB_DEVICE(0x046d, 0x0990), ++ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | ++ USB_DEVICE_ID_MATCH_INT_CLASS | ++ USB_DEVICE_ID_MATCH_INT_SUBCLASS, ++ .idVendor = 0x046d, ++ .idProduct = 0x0990, ++ .bInterfaceClass = USB_CLASS_AUDIO, ++ .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + .vendor_name = "Logitech, Inc.", + .product_name = "QuickCam Pro 9000", +@@ -1622,7 +1628,11 @@ YAMAHA_DEVICE(0x7010, "UB99"), + USB_DEVICE_VENDOR_SPEC(0x0582, 0x0108), + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + .ifnum = 0, +- .type = QUIRK_MIDI_STANDARD_INTERFACE ++ .type = QUIRK_MIDI_FIXED_ENDPOINT, ++ .data = & (const struct snd_usb_midi_endpoint_info) { ++ .out_cables = 0x0007, ++ .in_cables = 0x0007 ++ } + } + }, + { diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.49-50.patch b/patch/kernel/sun8i-default/0001-patch-3.4.49-50.patch new file mode 100644 index 000000000..a0f4bbc98 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.49-50.patch @@ -0,0 +1,1506 @@ +diff --git a/Makefile b/Makefile +index a36dada..6dd1ffb 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 49 ++SUBLEVEL = 50 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h +index d58fc4e..6afb13a 100644 +--- a/arch/powerpc/include/asm/exception-64s.h ++++ b/arch/powerpc/include/asm/exception-64s.h +@@ -320,7 +320,7 @@ label##_common: \ + */ + #define STD_EXCEPTION_COMMON_ASYNC(trap, label, hdlr) \ + EXCEPTION_COMMON(trap, label, hdlr, ret_from_except_lite, \ +- FINISH_NAP;RUNLATCH_ON;DISABLE_INTS) ++ FINISH_NAP;DISABLE_INTS;RUNLATCH_ON) + + /* + * When the idle code in power4_idle puts the CPU into NAP mode, +diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c +index d7ebc58..071592b 100644 +--- a/arch/powerpc/kernel/irq.c ++++ b/arch/powerpc/kernel/irq.c +@@ -162,7 +162,7 @@ notrace unsigned int __check_irq_replay(void) + * in case we also had a rollover while hard disabled + */ + local_paca->irq_happened &= ~PACA_IRQ_DEC; +- if (decrementer_check_overflow()) ++ if ((happened & PACA_IRQ_DEC) || decrementer_check_overflow()) + return 0x900; + + /* Finally check if an external interrupt happened */ +diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c +index 94178e5..c1aef40 100644 +--- a/arch/powerpc/kernel/process.c ++++ b/arch/powerpc/kernel/process.c +@@ -1218,7 +1218,7 @@ EXPORT_SYMBOL(dump_stack); + + #ifdef CONFIG_PPC64 + /* Called with hard IRQs off */ +-void __ppc64_runlatch_on(void) ++void notrace __ppc64_runlatch_on(void) + { + struct thread_info *ti = current_thread_info(); + unsigned long ctrl; +@@ -1231,7 +1231,7 @@ void __ppc64_runlatch_on(void) + } + + /* Called with hard IRQs off */ +-void __ppc64_runlatch_off(void) ++void notrace __ppc64_runlatch_off(void) + { + struct thread_info *ti = current_thread_info(); + unsigned long ctrl; +diff --git a/arch/x86/kernel/relocate_kernel_64.S b/arch/x86/kernel/relocate_kernel_64.S +index 7a6f3b3..f2bb9c9 100644 +--- a/arch/x86/kernel/relocate_kernel_64.S ++++ b/arch/x86/kernel/relocate_kernel_64.S +@@ -160,7 +160,7 @@ identity_mapped: + xorq %rbp, %rbp + xorq %r8, %r8 + xorq %r9, %r9 +- xorq %r10, %r9 ++ xorq %r10, %r10 + xorq %r11, %r11 + xorq %r12, %r12 + xorq %r13, %r13 +diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c +index b0f553b..d3446f6 100644 +--- a/drivers/block/cciss.c ++++ b/drivers/block/cciss.c +@@ -161,8 +161,6 @@ static irqreturn_t do_cciss_msix_intr(int irq, void *dev_id); + static int cciss_open(struct block_device *bdev, fmode_t mode); + static int cciss_unlocked_open(struct block_device *bdev, fmode_t mode); + static int cciss_release(struct gendisk *disk, fmode_t mode); +-static int do_ioctl(struct block_device *bdev, fmode_t mode, +- unsigned int cmd, unsigned long arg); + static int cciss_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long arg); + static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); +@@ -229,7 +227,7 @@ static const struct block_device_operations cciss_fops = { + .owner = THIS_MODULE, + .open = cciss_unlocked_open, + .release = cciss_release, +- .ioctl = do_ioctl, ++ .ioctl = cciss_ioctl, + .getgeo = cciss_getgeo, + #ifdef CONFIG_COMPAT + .compat_ioctl = cciss_compat_ioctl, +@@ -1140,16 +1138,6 @@ static int cciss_release(struct gendisk *disk, fmode_t mode) + return 0; + } + +-static int do_ioctl(struct block_device *bdev, fmode_t mode, +- unsigned cmd, unsigned long arg) +-{ +- int ret; +- mutex_lock(&cciss_mutex); +- ret = cciss_ioctl(bdev, mode, cmd, arg); +- mutex_unlock(&cciss_mutex); +- return ret; +-} +- + #ifdef CONFIG_COMPAT + + static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode, +@@ -1176,7 +1164,7 @@ static int cciss_compat_ioctl(struct block_device *bdev, fmode_t mode, + case CCISS_REGNEWD: + case CCISS_RESCANDISK: + case CCISS_GETLUNINFO: +- return do_ioctl(bdev, mode, cmd, arg); ++ return cciss_ioctl(bdev, mode, cmd, arg); + + case CCISS_PASSTHRU32: + return cciss_ioctl32_passthru(bdev, mode, cmd, arg); +@@ -1216,7 +1204,7 @@ static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode, + if (err) + return -EFAULT; + +- err = do_ioctl(bdev, mode, CCISS_PASSTHRU, (unsigned long)p); ++ err = cciss_ioctl(bdev, mode, CCISS_PASSTHRU, (unsigned long)p); + if (err) + return err; + err |= +@@ -1258,7 +1246,7 @@ static int cciss_ioctl32_big_passthru(struct block_device *bdev, fmode_t mode, + if (err) + return -EFAULT; + +- err = do_ioctl(bdev, mode, CCISS_BIG_PASSTHRU, (unsigned long)p); ++ err = cciss_ioctl(bdev, mode, CCISS_BIG_PASSTHRU, (unsigned long)p); + if (err) + return err; + err |= +@@ -1308,11 +1296,14 @@ static int cciss_getpciinfo(ctlr_info_t *h, void __user *argp) + static int cciss_getintinfo(ctlr_info_t *h, void __user *argp) + { + cciss_coalint_struct intinfo; ++ unsigned long flags; + + if (!argp) + return -EINVAL; ++ spin_lock_irqsave(&h->lock, flags); + intinfo.delay = readl(&h->cfgtable->HostWrite.CoalIntDelay); + intinfo.count = readl(&h->cfgtable->HostWrite.CoalIntCount); ++ spin_unlock_irqrestore(&h->lock, flags); + if (copy_to_user + (argp, &intinfo, sizeof(cciss_coalint_struct))) + return -EFAULT; +@@ -1353,12 +1344,15 @@ static int cciss_setintinfo(ctlr_info_t *h, void __user *argp) + static int cciss_getnodename(ctlr_info_t *h, void __user *argp) + { + NodeName_type NodeName; ++ unsigned long flags; + int i; + + if (!argp) + return -EINVAL; ++ spin_lock_irqsave(&h->lock, flags); + for (i = 0; i < 16; i++) + NodeName[i] = readb(&h->cfgtable->ServerName[i]); ++ spin_unlock_irqrestore(&h->lock, flags); + if (copy_to_user(argp, NodeName, sizeof(NodeName_type))) + return -EFAULT; + return 0; +@@ -1395,10 +1389,13 @@ static int cciss_setnodename(ctlr_info_t *h, void __user *argp) + static int cciss_getheartbeat(ctlr_info_t *h, void __user *argp) + { + Heartbeat_type heartbeat; ++ unsigned long flags; + + if (!argp) + return -EINVAL; ++ spin_lock_irqsave(&h->lock, flags); + heartbeat = readl(&h->cfgtable->HeartBeat); ++ spin_unlock_irqrestore(&h->lock, flags); + if (copy_to_user(argp, &heartbeat, sizeof(Heartbeat_type))) + return -EFAULT; + return 0; +@@ -1407,10 +1404,13 @@ static int cciss_getheartbeat(ctlr_info_t *h, void __user *argp) + static int cciss_getbustypes(ctlr_info_t *h, void __user *argp) + { + BusTypes_type BusTypes; ++ unsigned long flags; + + if (!argp) + return -EINVAL; ++ spin_lock_irqsave(&h->lock, flags); + BusTypes = readl(&h->cfgtable->BusTypes); ++ spin_unlock_irqrestore(&h->lock, flags); + if (copy_to_user(argp, &BusTypes, sizeof(BusTypes_type))) + return -EFAULT; + return 0; +diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c b/drivers/gpu/drm/gma500/cdv_intel_display.c +index be84559..1ee297b 100644 +--- a/drivers/gpu/drm/gma500/cdv_intel_display.c ++++ b/drivers/gpu/drm/gma500/cdv_intel_display.c +@@ -1439,6 +1439,19 @@ static void cdv_intel_crtc_destroy(struct drm_crtc *crtc) + kfree(psb_intel_crtc); + } + ++static void cdv_intel_crtc_disable(struct drm_crtc *crtc) ++{ ++ struct gtt_range *gt; ++ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; ++ ++ crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); ++ ++ if (crtc->fb) { ++ gt = to_psb_fb(crtc->fb)->gtt; ++ psb_gtt_unpin(gt); ++ } ++} ++ + const struct drm_crtc_helper_funcs cdv_intel_helper_funcs = { + .dpms = cdv_intel_crtc_dpms, + .mode_fixup = cdv_intel_crtc_mode_fixup, +@@ -1446,6 +1459,7 @@ const struct drm_crtc_helper_funcs cdv_intel_helper_funcs = { + .mode_set_base = cdv_intel_pipe_set_base, + .prepare = cdv_intel_crtc_prepare, + .commit = cdv_intel_crtc_commit, ++ .disable = cdv_intel_crtc_disable, + }; + + const struct drm_crtc_funcs cdv_intel_crtc_funcs = { +diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c +index 2616558..454a9d8 100644 +--- a/drivers/gpu/drm/gma500/psb_intel_display.c ++++ b/drivers/gpu/drm/gma500/psb_intel_display.c +@@ -1262,6 +1262,19 @@ void psb_intel_crtc_destroy(struct drm_crtc *crtc) + kfree(psb_intel_crtc); + } + ++static void psb_intel_crtc_disable(struct drm_crtc *crtc) ++{ ++ struct gtt_range *gt; ++ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; ++ ++ crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); ++ ++ if (crtc->fb) { ++ gt = to_psb_fb(crtc->fb)->gtt; ++ psb_gtt_unpin(gt); ++ } ++} ++ + const struct drm_crtc_helper_funcs psb_intel_helper_funcs = { + .dpms = psb_intel_crtc_dpms, + .mode_fixup = psb_intel_crtc_mode_fixup, +@@ -1269,6 +1282,7 @@ const struct drm_crtc_helper_funcs psb_intel_helper_funcs = { + .mode_set_base = psb_intel_pipe_set_base, + .prepare = psb_intel_crtc_prepare, + .commit = psb_intel_crtc_commit, ++ .disable = psb_intel_crtc_disable, + }; + + const struct drm_crtc_funcs psb_intel_crtc_funcs = { +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index aeb9d6e..c0ba260 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -1582,10 +1582,13 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) + * arranged in priority order. + */ + intel_ddc_get_modes(connector, &intel_sdvo->ddc); +- if (list_empty(&connector->probed_modes) == false) +- goto end; + +- /* Fetch modes from VBT */ ++ /* ++ * Fetch modes from VBT. For SDVO prefer the VBT mode since some ++ * SDVO->LVDS transcoders can't cope with the EDID mode. Since ++ * drm_mode_probed_add adds the mode at the head of the list we add it ++ * last. ++ */ + if (dev_priv->sdvo_lvds_vbt_mode != NULL) { + newmode = drm_mode_duplicate(connector->dev, + dev_priv->sdvo_lvds_vbt_mode); +@@ -1597,7 +1600,6 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) + } + } + +-end: + list_for_each_entry(newmode, &connector->probed_modes, head) { + if (newmode->type & DRM_MODE_TYPE_PREFERRED) { + intel_sdvo->sdvo_lvds_fixed_mode = +diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c +index df44509..b424a20 100644 +--- a/drivers/md/raid1.c ++++ b/drivers/md/raid1.c +@@ -413,7 +413,17 @@ static void raid1_end_write_request(struct bio *bio, int error) + + r1_bio->bios[mirror] = NULL; + to_put = bio; +- set_bit(R1BIO_Uptodate, &r1_bio->state); ++ /* ++ * Do not set R1BIO_Uptodate if the current device is ++ * rebuilding or Faulty. This is because we cannot use ++ * such device for properly reading the data back (we could ++ * potentially use it, if the current write would have felt ++ * before rdev->recovery_offset, but for simplicity we don't ++ * check this here. ++ */ ++ if (test_bit(In_sync, &conf->mirrors[mirror].rdev->flags) && ++ !test_bit(Faulty, &conf->mirrors[mirror].rdev->flags)) ++ set_bit(R1BIO_Uptodate, &r1_bio->state); + + /* Maybe we can clear some bad blocks. */ + if (is_badblock(conf->mirrors[mirror].rdev, +diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c +index 6137d00..0cc7985 100644 +--- a/drivers/md/raid10.c ++++ b/drivers/md/raid10.c +@@ -452,7 +452,17 @@ static void raid10_end_write_request(struct bio *bio, int error) + sector_t first_bad; + int bad_sectors; + +- set_bit(R10BIO_Uptodate, &r10_bio->state); ++ /* ++ * Do not set R10BIO_Uptodate if the current device is ++ * rebuilding or Faulty. This is because we cannot use ++ * such device for properly reading the data back (we could ++ * potentially use it, if the current write would have felt ++ * before rdev->recovery_offset, but for simplicity we don't ++ * check this here. ++ */ ++ if (test_bit(In_sync, &rdev->flags) && ++ !test_bit(Faulty, &rdev->flags)) ++ set_bit(R10BIO_Uptodate, &r10_bio->state); + + /* Maybe we can clear some bad blocks. */ + if (is_badblock(rdev, +diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig +index e507e78..3b8c930 100644 +--- a/drivers/net/wireless/ath/ath9k/Kconfig ++++ b/drivers/net/wireless/ath/ath9k/Kconfig +@@ -89,13 +89,17 @@ config ATH9K_MAC_DEBUG + This option enables collection of statistics for Rx/Tx status + data and some other MAC related statistics + +-config ATH9K_RATE_CONTROL ++config ATH9K_LEGACY_RATE_CONTROL + bool "Atheros ath9k rate control" + depends on ATH9K +- default y ++ default n + ---help--- + Say Y, if you want to use the ath9k specific rate control +- module instead of minstrel_ht. ++ module instead of minstrel_ht. Be warned that there are various ++ issues with the ath9k RC and minstrel is a more robust algorithm. ++ Note that even if this option is selected, "ath9k_rate_control" ++ has to be passed to mac80211 using the module parameter, ++ ieee80211_default_rc_algo. + + config ATH9K_HTC + tristate "Atheros HTC based wireless cards support" +diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile +index 27d95fe..24ae2e6 100644 +--- a/drivers/net/wireless/ath/ath9k/Makefile ++++ b/drivers/net/wireless/ath/ath9k/Makefile +@@ -6,7 +6,7 @@ ath9k-y += beacon.o \ + xmit.o + + ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o +-ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o ++ath9k-$(CONFIG_ATH9K_LEGACY_RATE_CONTROL) += rc.o + ath9k-$(CONFIG_ATH9K_PCI) += pci.o + ath9k-$(CONFIG_ATH9K_AHB) += ahb.o + ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o +diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c +index cb00645..cac5b25 100644 +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -671,8 +671,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) + BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_MESH_POINT); + +- if (AR_SREV_5416(sc->sc_ah)) +- hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; ++ hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + + hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; + hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; +@@ -695,10 +694,6 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) + sc->ant_rx = hw->wiphy->available_antennas_rx; + sc->ant_tx = hw->wiphy->available_antennas_tx; + +-#ifdef CONFIG_ATH9K_RATE_CONTROL +- hw->rate_control_algorithm = "ath9k_rate_control"; +-#endif +- + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) + hw->wiphy->bands[IEEE80211_BAND_2GHZ] = + &sc->sbands[IEEE80211_BAND_2GHZ]; +diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h +index 75f8e9b..12cf122 100644 +--- a/drivers/net/wireless/ath/ath9k/rc.h ++++ b/drivers/net/wireless/ath/ath9k/rc.h +@@ -219,7 +219,7 @@ struct ath_rate_priv { + struct ath_rc_stats rcstats[RATE_TABLE_SIZE]; + }; + +-#ifdef CONFIG_ATH9K_RATE_CONTROL ++#ifdef CONFIG_ATH9K_LEGACY_RATE_CONTROL + int ath_rate_control_register(void); + void ath_rate_control_unregister(void); + #else +diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c +index b54c750..f8c4499 100644 +--- a/drivers/net/wireless/b43/main.c ++++ b/drivers/net/wireless/b43/main.c +@@ -2449,7 +2449,7 @@ static void b43_request_firmware(struct work_struct *work) + for (i = 0; i < B43_NR_FWTYPES; i++) { + errmsg = ctx->errors[i]; + if (strlen(errmsg)) +- b43err(dev->wl, errmsg); ++ b43err(dev->wl, "%s", errmsg); + } + b43_print_fw_helptext(dev->wl, 1); + goto out; +diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c +index 63ccc0f..c5ce195 100644 +--- a/drivers/rtc/rtc-twl.c ++++ b/drivers/rtc/rtc-twl.c +@@ -523,6 +523,7 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev) + } + + platform_set_drvdata(pdev, rtc); ++ device_init_wakeup(&pdev->dev, 1); + return 0; + + out2: +diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c +index 80576d05..bb5fb3d 100644 +--- a/fs/ceph/locks.c ++++ b/fs/ceph/locks.c +@@ -191,27 +191,23 @@ void ceph_count_locks(struct inode *inode, int *fcntl_count, int *flock_count) + } + + /** +- * Encode the flock and fcntl locks for the given inode into the pagelist. +- * Format is: #fcntl locks, sequential fcntl locks, #flock locks, +- * sequential flock locks. +- * Must be called with lock_flocks() already held. +- * If we encounter more of a specific lock type than expected, +- * we return the value 1. ++ * Encode the flock and fcntl locks for the given inode into the ceph_filelock ++ * array. Must be called with lock_flocks() already held. ++ * If we encounter more of a specific lock type than expected, return -ENOSPC. + */ +-int ceph_encode_locks(struct inode *inode, struct ceph_pagelist *pagelist, +- int num_fcntl_locks, int num_flock_locks) ++int ceph_encode_locks_to_buffer(struct inode *inode, ++ struct ceph_filelock *flocks, ++ int num_fcntl_locks, int num_flock_locks) + { + struct file_lock *lock; +- struct ceph_filelock cephlock; + int err = 0; + int seen_fcntl = 0; + int seen_flock = 0; ++ int l = 0; + + dout("encoding %d flock and %d fcntl locks", num_flock_locks, + num_fcntl_locks); +- err = ceph_pagelist_append(pagelist, &num_fcntl_locks, sizeof(u32)); +- if (err) +- goto fail; ++ + for (lock = inode->i_flock; lock != NULL; lock = lock->fl_next) { + if (lock->fl_flags & FL_POSIX) { + ++seen_fcntl; +@@ -219,19 +215,12 @@ int ceph_encode_locks(struct inode *inode, struct ceph_pagelist *pagelist, + err = -ENOSPC; + goto fail; + } +- err = lock_to_ceph_filelock(lock, &cephlock); ++ err = lock_to_ceph_filelock(lock, &flocks[l]); + if (err) + goto fail; +- err = ceph_pagelist_append(pagelist, &cephlock, +- sizeof(struct ceph_filelock)); ++ ++l; + } +- if (err) +- goto fail; + } +- +- err = ceph_pagelist_append(pagelist, &num_flock_locks, sizeof(u32)); +- if (err) +- goto fail; + for (lock = inode->i_flock; lock != NULL; lock = lock->fl_next) { + if (lock->fl_flags & FL_FLOCK) { + ++seen_flock; +@@ -239,19 +228,51 @@ int ceph_encode_locks(struct inode *inode, struct ceph_pagelist *pagelist, + err = -ENOSPC; + goto fail; + } +- err = lock_to_ceph_filelock(lock, &cephlock); ++ err = lock_to_ceph_filelock(lock, &flocks[l]); + if (err) + goto fail; +- err = ceph_pagelist_append(pagelist, &cephlock, +- sizeof(struct ceph_filelock)); ++ ++l; + } +- if (err) +- goto fail; + } + fail: + return err; + } + ++/** ++ * Copy the encoded flock and fcntl locks into the pagelist. ++ * Format is: #fcntl locks, sequential fcntl locks, #flock locks, ++ * sequential flock locks. ++ * Returns zero on success. ++ */ ++int ceph_locks_to_pagelist(struct ceph_filelock *flocks, ++ struct ceph_pagelist *pagelist, ++ int num_fcntl_locks, int num_flock_locks) ++{ ++ int err = 0; ++ __le32 nlocks; ++ ++ nlocks = cpu_to_le32(num_fcntl_locks); ++ err = ceph_pagelist_append(pagelist, &nlocks, sizeof(nlocks)); ++ if (err) ++ goto out_fail; ++ ++ err = ceph_pagelist_append(pagelist, flocks, ++ num_fcntl_locks * sizeof(*flocks)); ++ if (err) ++ goto out_fail; ++ ++ nlocks = cpu_to_le32(num_flock_locks); ++ err = ceph_pagelist_append(pagelist, &nlocks, sizeof(nlocks)); ++ if (err) ++ goto out_fail; ++ ++ err = ceph_pagelist_append(pagelist, ++ &flocks[num_fcntl_locks], ++ num_flock_locks * sizeof(*flocks)); ++out_fail: ++ return err; ++} ++ + /* + * Given a pointer to a lock, convert it to a ceph filelock + */ +diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c +index 3fd08ad..cf1b9e0 100644 +--- a/fs/ceph/mds_client.c ++++ b/fs/ceph/mds_client.c +@@ -335,9 +335,9 @@ void ceph_put_mds_session(struct ceph_mds_session *s) + atomic_read(&s->s_ref), atomic_read(&s->s_ref)-1); + if (atomic_dec_and_test(&s->s_ref)) { + if (s->s_auth.authorizer) +- s->s_mdsc->fsc->client->monc.auth->ops->destroy_authorizer( +- s->s_mdsc->fsc->client->monc.auth, +- s->s_auth.authorizer); ++ ceph_auth_destroy_authorizer( ++ s->s_mdsc->fsc->client->monc.auth, ++ s->s_auth.authorizer); + kfree(s); + } + } +@@ -2455,39 +2455,44 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, + + if (recon_state->flock) { + int num_fcntl_locks, num_flock_locks; +- struct ceph_pagelist_cursor trunc_point; +- +- ceph_pagelist_set_cursor(pagelist, &trunc_point); +- do { +- lock_flocks(); +- ceph_count_locks(inode, &num_fcntl_locks, +- &num_flock_locks); +- rec.v2.flock_len = (2*sizeof(u32) + +- (num_fcntl_locks+num_flock_locks) * +- sizeof(struct ceph_filelock)); +- unlock_flocks(); +- +- /* pre-alloc pagelist */ +- ceph_pagelist_truncate(pagelist, &trunc_point); +- err = ceph_pagelist_append(pagelist, &rec, reclen); +- if (!err) +- err = ceph_pagelist_reserve(pagelist, +- rec.v2.flock_len); +- +- /* encode locks */ +- if (!err) { +- lock_flocks(); +- err = ceph_encode_locks(inode, +- pagelist, +- num_fcntl_locks, +- num_flock_locks); +- unlock_flocks(); +- } +- } while (err == -ENOSPC); ++ struct ceph_filelock *flocks; ++ ++encode_again: ++ lock_flocks(); ++ ceph_count_locks(inode, &num_fcntl_locks, &num_flock_locks); ++ unlock_flocks(); ++ flocks = kmalloc((num_fcntl_locks+num_flock_locks) * ++ sizeof(struct ceph_filelock), GFP_NOFS); ++ if (!flocks) { ++ err = -ENOMEM; ++ goto out_free; ++ } ++ lock_flocks(); ++ err = ceph_encode_locks_to_buffer(inode, flocks, ++ num_fcntl_locks, ++ num_flock_locks); ++ unlock_flocks(); ++ if (err) { ++ kfree(flocks); ++ if (err == -ENOSPC) ++ goto encode_again; ++ goto out_free; ++ } ++ /* ++ * number of encoded locks is stable, so copy to pagelist ++ */ ++ rec.v2.flock_len = cpu_to_le32(2*sizeof(u32) + ++ (num_fcntl_locks+num_flock_locks) * ++ sizeof(struct ceph_filelock)); ++ err = ceph_pagelist_append(pagelist, &rec, reclen); ++ if (!err) ++ err = ceph_locks_to_pagelist(flocks, pagelist, ++ num_fcntl_locks, ++ num_flock_locks); ++ kfree(flocks); + } else { + err = ceph_pagelist_append(pagelist, &rec, reclen); + } +- + out_free: + kfree(path); + out_dput: +@@ -3414,13 +3419,17 @@ static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con, + struct ceph_auth_handshake *auth = &s->s_auth; + + if (force_new && auth->authorizer) { +- if (ac->ops && ac->ops->destroy_authorizer) +- ac->ops->destroy_authorizer(ac, auth->authorizer); ++ ceph_auth_destroy_authorizer(ac, auth->authorizer); + auth->authorizer = NULL; + } +- if (!auth->authorizer && ac->ops && ac->ops->create_authorizer) { +- int ret = ac->ops->create_authorizer(ac, CEPH_ENTITY_TYPE_MDS, +- auth); ++ if (!auth->authorizer) { ++ int ret = ceph_auth_create_authorizer(ac, CEPH_ENTITY_TYPE_MDS, ++ auth); ++ if (ret) ++ return ERR_PTR(ret); ++ } else { ++ int ret = ceph_auth_update_authorizer(ac, CEPH_ENTITY_TYPE_MDS, ++ auth); + if (ret) + return ERR_PTR(ret); + } +@@ -3436,7 +3445,7 @@ static int verify_authorizer_reply(struct ceph_connection *con, int len) + struct ceph_mds_client *mdsc = s->s_mdsc; + struct ceph_auth_client *ac = mdsc->fsc->client->monc.auth; + +- return ac->ops->verify_authorizer_reply(ac, s->s_auth.authorizer, len); ++ return ceph_auth_verify_authorizer_reply(ac, s->s_auth.authorizer, len); + } + + static int invalidate_authorizer(struct ceph_connection *con) +@@ -3445,8 +3454,7 @@ static int invalidate_authorizer(struct ceph_connection *con) + struct ceph_mds_client *mdsc = s->s_mdsc; + struct ceph_auth_client *ac = mdsc->fsc->client->monc.auth; + +- if (ac->ops->invalidate_authorizer) +- ac->ops->invalidate_authorizer(ac, CEPH_ENTITY_TYPE_MDS); ++ ceph_auth_invalidate_authorizer(ac, CEPH_ENTITY_TYPE_MDS); + + return ceph_monc_validate_auth(&mdsc->fsc->client->monc); + } +diff --git a/fs/ceph/super.c b/fs/ceph/super.c +index f363918..f4fa5cf 100644 +--- a/fs/ceph/super.c ++++ b/fs/ceph/super.c +@@ -70,8 +70,14 @@ static int ceph_statfs(struct dentry *dentry, struct kstatfs *buf) + /* + * express utilization in terms of large blocks to avoid + * overflow on 32-bit machines. ++ * ++ * NOTE: for the time being, we make bsize == frsize to humor ++ * not-yet-ancient versions of glibc that are broken. ++ * Someday, we will probably want to report a real block ++ * size... whatever that may mean for a network file system! + */ + buf->f_bsize = 1 << CEPH_BLOCK_SHIFT; ++ buf->f_frsize = 1 << CEPH_BLOCK_SHIFT; + buf->f_blocks = le64_to_cpu(st.kb) >> (CEPH_BLOCK_SHIFT-10); + buf->f_bfree = le64_to_cpu(st.kb_avail) >> (CEPH_BLOCK_SHIFT-10); + buf->f_bavail = le64_to_cpu(st.kb_avail) >> (CEPH_BLOCK_SHIFT-10); +@@ -79,7 +85,6 @@ static int ceph_statfs(struct dentry *dentry, struct kstatfs *buf) + buf->f_files = le64_to_cpu(st.num_objects); + buf->f_ffree = -1; + buf->f_namelen = NAME_MAX; +- buf->f_frsize = PAGE_CACHE_SIZE; + + /* leave fsid little-endian, regardless of host endianness */ + fsid = *(u64 *)(&monmap->fsid) ^ *((u64 *)&monmap->fsid + 1); +diff --git a/fs/ceph/super.h b/fs/ceph/super.h +index fc35036..d2e01a6 100644 +--- a/fs/ceph/super.h ++++ b/fs/ceph/super.h +@@ -21,7 +21,7 @@ + + /* large granularity for statfs utilization stats to facilitate + * large volume sizes on 32-bit machines. */ +-#define CEPH_BLOCK_SHIFT 20 /* 1 MB */ ++#define CEPH_BLOCK_SHIFT 22 /* 4 MB */ + #define CEPH_BLOCK (1 << CEPH_BLOCK_SHIFT) + + #define CEPH_MOUNT_OPT_DIRSTAT (1<<4) /* `cat dirname` for stats */ +@@ -847,8 +847,13 @@ extern const struct export_operations ceph_export_ops; + extern int ceph_lock(struct file *file, int cmd, struct file_lock *fl); + extern int ceph_flock(struct file *file, int cmd, struct file_lock *fl); + extern void ceph_count_locks(struct inode *inode, int *p_num, int *f_num); +-extern int ceph_encode_locks(struct inode *i, struct ceph_pagelist *p, +- int p_locks, int f_locks); ++extern int ceph_encode_locks_to_buffer(struct inode *inode, ++ struct ceph_filelock *flocks, ++ int num_fcntl_locks, ++ int num_flock_locks); ++extern int ceph_locks_to_pagelist(struct ceph_filelock *flocks, ++ struct ceph_pagelist *pagelist, ++ int num_fcntl_locks, int num_flock_locks); + extern int lock_to_ceph_filelock(struct file_lock *fl, struct ceph_filelock *c); + + /* debugfs.c */ +diff --git a/include/linux/ceph/auth.h b/include/linux/ceph/auth.h +index d4080f3..5f33868 100644 +--- a/include/linux/ceph/auth.h ++++ b/include/linux/ceph/auth.h +@@ -52,6 +52,9 @@ struct ceph_auth_client_ops { + */ + int (*create_authorizer)(struct ceph_auth_client *ac, int peer_type, + struct ceph_auth_handshake *auth); ++ /* ensure that an existing authorizer is up to date */ ++ int (*update_authorizer)(struct ceph_auth_client *ac, int peer_type, ++ struct ceph_auth_handshake *auth); + int (*verify_authorizer_reply)(struct ceph_auth_client *ac, + struct ceph_authorizer *a, size_t len); + void (*destroy_authorizer)(struct ceph_auth_client *ac, +@@ -75,6 +78,8 @@ struct ceph_auth_client { + u64 global_id; /* our unique id in system */ + const struct ceph_crypto_key *key; /* our secret key */ + unsigned want_keys; /* which services we want */ ++ ++ struct mutex mutex; + }; + + extern struct ceph_auth_client *ceph_auth_init(const char *name, +@@ -94,5 +99,18 @@ extern int ceph_build_auth(struct ceph_auth_client *ac, + void *msg_buf, size_t msg_len); + + extern int ceph_auth_is_authenticated(struct ceph_auth_client *ac); ++extern int ceph_auth_create_authorizer(struct ceph_auth_client *ac, ++ int peer_type, ++ struct ceph_auth_handshake *auth); ++extern void ceph_auth_destroy_authorizer(struct ceph_auth_client *ac, ++ struct ceph_authorizer *a); ++extern int ceph_auth_update_authorizer(struct ceph_auth_client *ac, ++ int peer_type, ++ struct ceph_auth_handshake *a); ++extern int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac, ++ struct ceph_authorizer *a, ++ size_t len); ++extern void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac, ++ int peer_type); + + #endif +diff --git a/include/linux/cpu.h b/include/linux/cpu.h +index 78ed62f..25fd741 100644 +--- a/include/linux/cpu.h ++++ b/include/linux/cpu.h +@@ -177,6 +177,8 @@ extern struct bus_type cpu_subsys; + + extern void get_online_cpus(void); + extern void put_online_cpus(void); ++extern void cpu_hotplug_disable(void); ++extern void cpu_hotplug_enable(void); + #define hotcpu_notifier(fn, pri) cpu_notifier(fn, pri) + #define register_hotcpu_notifier(nb) register_cpu_notifier(nb) + #define unregister_hotcpu_notifier(nb) unregister_cpu_notifier(nb) +@@ -199,6 +201,8 @@ static inline void cpu_hotplug_driver_unlock(void) + + #define get_online_cpus() do { } while (0) + #define put_online_cpus() do { } while (0) ++#define cpu_hotplug_disable() do { } while (0) ++#define cpu_hotplug_enable() do { } while (0) + #define hotcpu_notifier(fn, pri) do { (void)(fn); } while (0) + /* These aren't inline functions due to a GCC bug. */ + #define register_hotcpu_notifier(nb) ({ (void)(nb); 0; }) +diff --git a/include/linux/swapops.h b/include/linux/swapops.h +index 47ead51..c5fd30d 100644 +--- a/include/linux/swapops.h ++++ b/include/linux/swapops.h +@@ -137,6 +137,7 @@ static inline void make_migration_entry_read(swp_entry_t *entry) + + extern void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, + unsigned long address); ++extern void migration_entry_wait_huge(struct mm_struct *mm, pte_t *pte); + #else + + #define make_migration_entry(page, write) swp_entry(0, 0) +@@ -148,6 +149,8 @@ static inline int is_migration_entry(swp_entry_t swp) + static inline void make_migration_entry_read(swp_entry_t *entryp) { } + static inline void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, + unsigned long address) { } ++static inline void migration_entry_wait_huge(struct mm_struct *mm, ++ pte_t *pte) { } + static inline int is_write_migration_entry(swp_entry_t entry) + { + return 0; +diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h +index db1c5df..4886c11 100644 +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -976,6 +976,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event); + int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); + int mgmt_index_added(struct hci_dev *hdev); + int mgmt_index_removed(struct hci_dev *hdev); ++int mgmt_set_powered_failed(struct hci_dev *hdev, int err); + int mgmt_powered(struct hci_dev *hdev, u8 powered); + int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable); + int mgmt_connectable(struct hci_dev *hdev, u8 connectable); +diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h +index ebfd91f..8098e87 100644 +--- a/include/net/bluetooth/mgmt.h ++++ b/include/net/bluetooth/mgmt.h +@@ -42,6 +42,7 @@ + #define MGMT_STATUS_NOT_POWERED 0x0f + #define MGMT_STATUS_CANCELLED 0x10 + #define MGMT_STATUS_INVALID_INDEX 0x11 ++#define MGMT_STATUS_RFKILLED 0x12 + + struct mgmt_hdr { + __le16 opcode; +diff --git a/kernel/cpu.c b/kernel/cpu.c +index 2060c6e..26feaa9 100644 +--- a/kernel/cpu.c ++++ b/kernel/cpu.c +@@ -124,6 +124,27 @@ static void cpu_hotplug_done(void) + mutex_unlock(&cpu_hotplug.lock); + } + ++/* ++ * Wait for currently running CPU hotplug operations to complete (if any) and ++ * disable future CPU hotplug (from sysfs). The 'cpu_add_remove_lock' protects ++ * the 'cpu_hotplug_disabled' flag. The same lock is also acquired by the ++ * hotplug path before performing hotplug operations. So acquiring that lock ++ * guarantees mutual exclusion from any currently running hotplug operations. ++ */ ++void cpu_hotplug_disable(void) ++{ ++ cpu_maps_update_begin(); ++ cpu_hotplug_disabled = 1; ++ cpu_maps_update_done(); ++} ++ ++void cpu_hotplug_enable(void) ++{ ++ cpu_maps_update_begin(); ++ cpu_hotplug_disabled = 0; ++ cpu_maps_update_done(); ++} ++ + #else /* #if CONFIG_HOTPLUG_CPU */ + static void cpu_hotplug_begin(void) {} + static void cpu_hotplug_done(void) {} +@@ -479,36 +500,6 @@ static int __init alloc_frozen_cpus(void) + core_initcall(alloc_frozen_cpus); + + /* +- * Prevent regular CPU hotplug from racing with the freezer, by disabling CPU +- * hotplug when tasks are about to be frozen. Also, don't allow the freezer +- * to continue until any currently running CPU hotplug operation gets +- * completed. +- * To modify the 'cpu_hotplug_disabled' flag, we need to acquire the +- * 'cpu_add_remove_lock'. And this same lock is also taken by the regular +- * CPU hotplug path and released only after it is complete. Thus, we +- * (and hence the freezer) will block here until any currently running CPU +- * hotplug operation gets completed. +- */ +-void cpu_hotplug_disable_before_freeze(void) +-{ +- cpu_maps_update_begin(); +- cpu_hotplug_disabled = 1; +- cpu_maps_update_done(); +-} +- +- +-/* +- * When tasks have been thawed, re-enable regular CPU hotplug (which had been +- * disabled while beginning to freeze tasks). +- */ +-void cpu_hotplug_enable_after_thaw(void) +-{ +- cpu_maps_update_begin(); +- cpu_hotplug_disabled = 0; +- cpu_maps_update_done(); +-} +- +-/* + * When callbacks for CPU hotplug notifications are being executed, we must + * ensure that the state of the system with respect to the tasks being frozen + * or not, as reported by the notification, remains unchanged *throughout the +@@ -527,12 +518,12 @@ cpu_hotplug_pm_callback(struct notifier_block *nb, + + case PM_SUSPEND_PREPARE: + case PM_HIBERNATION_PREPARE: +- cpu_hotplug_disable_before_freeze(); ++ cpu_hotplug_disable(); + break; + + case PM_POST_SUSPEND: + case PM_POST_HIBERNATION: +- cpu_hotplug_enable_after_thaw(); ++ cpu_hotplug_enable(); + break; + + default: +diff --git a/kernel/sys.c b/kernel/sys.c +index 6a74b83..3449d26 100644 +--- a/kernel/sys.c ++++ b/kernel/sys.c +@@ -353,6 +353,29 @@ int unregister_reboot_notifier(struct notifier_block *nb) + } + EXPORT_SYMBOL(unregister_reboot_notifier); + ++/* Add backwards compatibility for stable trees. */ ++#ifndef PF_NO_SETAFFINITY ++#define PF_NO_SETAFFINITY PF_THREAD_BOUND ++#endif ++ ++static void migrate_to_reboot_cpu(void) ++{ ++ /* The boot cpu is always logical cpu 0 */ ++ int cpu = 0; ++ ++ cpu_hotplug_disable(); ++ ++ /* Make certain the cpu I'm about to reboot on is online */ ++ if (!cpu_online(cpu)) ++ cpu = cpumask_first(cpu_online_mask); ++ ++ /* Prevent races with other tasks migrating this task */ ++ current->flags |= PF_NO_SETAFFINITY; ++ ++ /* Make certain I only run on the appropriate processor */ ++ set_cpus_allowed_ptr(current, cpumask_of(cpu)); ++} ++ + /** + * kernel_restart - reboot the system + * @cmd: pointer to buffer containing command to execute for restart +@@ -364,7 +387,7 @@ EXPORT_SYMBOL(unregister_reboot_notifier); + void kernel_restart(char *cmd) + { + kernel_restart_prepare(cmd); +- disable_nonboot_cpus(); ++ migrate_to_reboot_cpu(); + syscore_shutdown(); + if (!cmd) + printk(KERN_EMERG "Restarting system.\n"); +@@ -391,7 +414,7 @@ static void kernel_shutdown_prepare(enum system_states state) + void kernel_halt(void) + { + kernel_shutdown_prepare(SYSTEM_HALT); +- disable_nonboot_cpus(); ++ migrate_to_reboot_cpu(); + syscore_shutdown(); + printk(KERN_EMERG "System halted.\n"); + kmsg_dump(KMSG_DUMP_HALT); +@@ -410,7 +433,7 @@ void kernel_power_off(void) + kernel_shutdown_prepare(SYSTEM_POWER_OFF); + if (pm_power_off_prepare) + pm_power_off_prepare(); +- disable_nonboot_cpus(); ++ migrate_to_reboot_cpu(); + syscore_shutdown(); + printk(KERN_EMERG "Power down.\n"); + kmsg_dump(KMSG_DUMP_POWEROFF); +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index 69b21bb..a692439 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -2768,7 +2768,7 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, + if (ptep) { + entry = huge_ptep_get(ptep); + if (unlikely(is_hugetlb_entry_migration(entry))) { +- migration_entry_wait(mm, (pmd_t *)ptep, address); ++ migration_entry_wait_huge(mm, ptep); + return 0; + } else if (unlikely(is_hugetlb_entry_hwpoisoned(entry))) + return VM_FAULT_HWPOISON_LARGE | +diff --git a/mm/migrate.c b/mm/migrate.c +index 37cd07b..5f588b1 100644 +--- a/mm/migrate.c ++++ b/mm/migrate.c +@@ -180,15 +180,14 @@ static void remove_migration_ptes(struct page *old, struct page *new) + * get to the page and wait until migration is finished. + * When we return from this function the fault will be retried. + */ +-void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, +- unsigned long address) ++static void __migration_entry_wait(struct mm_struct *mm, pte_t *ptep, ++ spinlock_t *ptl) + { +- pte_t *ptep, pte; +- spinlock_t *ptl; ++ pte_t pte; + swp_entry_t entry; + struct page *page; + +- ptep = pte_offset_map_lock(mm, pmd, address, &ptl); ++ spin_lock(ptl); + pte = *ptep; + if (!is_swap_pte(pte)) + goto out; +@@ -216,6 +215,20 @@ out: + pte_unmap_unlock(ptep, ptl); + } + ++void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, ++ unsigned long address) ++{ ++ spinlock_t *ptl = pte_lockptr(mm, pmd); ++ pte_t *ptep = pte_offset_map(pmd, address); ++ __migration_entry_wait(mm, ptep, ptl); ++} ++ ++void migration_entry_wait_huge(struct mm_struct *mm, pte_t *pte) ++{ ++ spinlock_t *ptl = &(mm)->page_table_lock; ++ __migration_entry_wait(mm, pte, ptl); ++} ++ + #ifdef CONFIG_BLOCK + /* Returns true if all buffers are successfully locked */ + static bool buffer_migrate_lock_buffers(struct buffer_head *head, +diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c +index 13b6c28..9197ae7 100644 +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -1120,11 +1120,15 @@ EXPORT_SYMBOL(hci_free_dev); + static void hci_power_on(struct work_struct *work) + { + struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); ++ int err; + + BT_DBG("%s", hdev->name); + +- if (hci_dev_open(hdev->id) < 0) ++ err = hci_dev_open(hdev->id); ++ if (err < 0) { ++ mgmt_set_powered_failed(hdev, err); + return; ++ } + + if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) + schedule_delayed_work(&hdev->power_off, +diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c +index 8f3d9dc..9f2f206 100644 +--- a/net/bluetooth/mgmt.c ++++ b/net/bluetooth/mgmt.c +@@ -2833,6 +2833,27 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered) + return err; + } + ++int mgmt_set_powered_failed(struct hci_dev *hdev, int err) ++{ ++ struct pending_cmd *cmd; ++ u8 status; ++ ++ cmd = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev); ++ if (!cmd) ++ return -ENOENT; ++ ++ if (err == -ERFKILL) ++ status = MGMT_STATUS_RFKILLED; ++ else ++ status = MGMT_STATUS_FAILED; ++ ++ err = cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_POWERED, status); ++ ++ mgmt_pending_remove(cmd); ++ ++ return err; ++} ++ + int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable) + { + struct cmd_lookup match = { NULL, hdev }; +diff --git a/net/ceph/auth.c b/net/ceph/auth.c +index b4bf4ac..6b923bc 100644 +--- a/net/ceph/auth.c ++++ b/net/ceph/auth.c +@@ -47,6 +47,7 @@ struct ceph_auth_client *ceph_auth_init(const char *name, const struct ceph_cryp + if (!ac) + goto out; + ++ mutex_init(&ac->mutex); + ac->negotiating = true; + if (name) + ac->name = name; +@@ -73,10 +74,12 @@ void ceph_auth_destroy(struct ceph_auth_client *ac) + */ + void ceph_auth_reset(struct ceph_auth_client *ac) + { ++ mutex_lock(&ac->mutex); + dout("auth_reset %p\n", ac); + if (ac->ops && !ac->negotiating) + ac->ops->reset(ac); + ac->negotiating = true; ++ mutex_unlock(&ac->mutex); + } + + int ceph_entity_name_encode(const char *name, void **p, void *end) +@@ -102,6 +105,7 @@ int ceph_auth_build_hello(struct ceph_auth_client *ac, void *buf, size_t len) + int i, num; + int ret; + ++ mutex_lock(&ac->mutex); + dout("auth_build_hello\n"); + monhdr->have_version = 0; + monhdr->session_mon = cpu_to_le16(-1); +@@ -122,15 +126,19 @@ int ceph_auth_build_hello(struct ceph_auth_client *ac, void *buf, size_t len) + + ret = ceph_entity_name_encode(ac->name, &p, end); + if (ret < 0) +- return ret; ++ goto out; + ceph_decode_need(&p, end, sizeof(u64), bad); + ceph_encode_64(&p, ac->global_id); + + ceph_encode_32(&lenp, p - lenp - sizeof(u32)); +- return p - buf; ++ ret = p - buf; ++out: ++ mutex_unlock(&ac->mutex); ++ return ret; + + bad: +- return -ERANGE; ++ ret = -ERANGE; ++ goto out; + } + + static int ceph_build_auth_request(struct ceph_auth_client *ac, +@@ -151,11 +159,13 @@ static int ceph_build_auth_request(struct ceph_auth_client *ac, + if (ret < 0) { + pr_err("error %d building auth method %s request\n", ret, + ac->ops->name); +- return ret; ++ goto out; + } + dout(" built request %d bytes\n", ret); + ceph_encode_32(&p, ret); +- return p + ret - msg_buf; ++ ret = p + ret - msg_buf; ++out: ++ return ret; + } + + /* +@@ -176,6 +186,7 @@ int ceph_handle_auth_reply(struct ceph_auth_client *ac, + int result_msg_len; + int ret = -EINVAL; + ++ mutex_lock(&ac->mutex); + dout("handle_auth_reply %p %p\n", p, end); + ceph_decode_need(&p, end, sizeof(u32) * 3 + sizeof(u64), bad); + protocol = ceph_decode_32(&p); +@@ -227,33 +238,103 @@ int ceph_handle_auth_reply(struct ceph_auth_client *ac, + + ret = ac->ops->handle_reply(ac, result, payload, payload_end); + if (ret == -EAGAIN) { +- return ceph_build_auth_request(ac, reply_buf, reply_len); ++ ret = ceph_build_auth_request(ac, reply_buf, reply_len); + } else if (ret) { + pr_err("auth method '%s' error %d\n", ac->ops->name, ret); +- return ret; + } +- return 0; + +-bad: +- pr_err("failed to decode auth msg\n"); + out: ++ mutex_unlock(&ac->mutex); + return ret; ++ ++bad: ++ pr_err("failed to decode auth msg\n"); ++ ret = -EINVAL; ++ goto out; + } + + int ceph_build_auth(struct ceph_auth_client *ac, + void *msg_buf, size_t msg_len) + { ++ int ret = 0; ++ ++ mutex_lock(&ac->mutex); + if (!ac->protocol) +- return ceph_auth_build_hello(ac, msg_buf, msg_len); +- BUG_ON(!ac->ops); +- if (ac->ops->should_authenticate(ac)) +- return ceph_build_auth_request(ac, msg_buf, msg_len); +- return 0; ++ ret = ceph_auth_build_hello(ac, msg_buf, msg_len); ++ else if (ac->ops->should_authenticate(ac)) ++ ret = ceph_build_auth_request(ac, msg_buf, msg_len); ++ mutex_unlock(&ac->mutex); ++ return ret; + } + + int ceph_auth_is_authenticated(struct ceph_auth_client *ac) + { +- if (!ac->ops) +- return 0; +- return ac->ops->is_authenticated(ac); ++ int ret = 0; ++ ++ mutex_lock(&ac->mutex); ++ if (ac->ops) ++ ret = ac->ops->is_authenticated(ac); ++ mutex_unlock(&ac->mutex); ++ return ret; ++} ++EXPORT_SYMBOL(ceph_auth_is_authenticated); ++ ++int ceph_auth_create_authorizer(struct ceph_auth_client *ac, ++ int peer_type, ++ struct ceph_auth_handshake *auth) ++{ ++ int ret = 0; ++ ++ mutex_lock(&ac->mutex); ++ if (ac->ops && ac->ops->create_authorizer) ++ ret = ac->ops->create_authorizer(ac, peer_type, auth); ++ mutex_unlock(&ac->mutex); ++ return ret; ++} ++EXPORT_SYMBOL(ceph_auth_create_authorizer); ++ ++void ceph_auth_destroy_authorizer(struct ceph_auth_client *ac, ++ struct ceph_authorizer *a) ++{ ++ mutex_lock(&ac->mutex); ++ if (ac->ops && ac->ops->destroy_authorizer) ++ ac->ops->destroy_authorizer(ac, a); ++ mutex_unlock(&ac->mutex); ++} ++EXPORT_SYMBOL(ceph_auth_destroy_authorizer); ++ ++int ceph_auth_update_authorizer(struct ceph_auth_client *ac, ++ int peer_type, ++ struct ceph_auth_handshake *a) ++{ ++ int ret = 0; ++ ++ mutex_lock(&ac->mutex); ++ if (ac->ops && ac->ops->update_authorizer) ++ ret = ac->ops->update_authorizer(ac, peer_type, a); ++ mutex_unlock(&ac->mutex); ++ return ret; ++} ++EXPORT_SYMBOL(ceph_auth_update_authorizer); ++ ++int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac, ++ struct ceph_authorizer *a, size_t len) ++{ ++ int ret = 0; ++ ++ mutex_lock(&ac->mutex); ++ if (ac->ops && ac->ops->verify_authorizer_reply) ++ ret = ac->ops->verify_authorizer_reply(ac, a, len); ++ mutex_unlock(&ac->mutex); ++ return ret; ++} ++EXPORT_SYMBOL(ceph_auth_verify_authorizer_reply); ++ ++void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac, int peer_type) ++{ ++ mutex_lock(&ac->mutex); ++ if (ac->ops && ac->ops->invalidate_authorizer) ++ ac->ops->invalidate_authorizer(ac, peer_type); ++ mutex_unlock(&ac->mutex); + } ++EXPORT_SYMBOL(ceph_auth_invalidate_authorizer); +diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c +index a16bf14..96238ba 100644 +--- a/net/ceph/auth_x.c ++++ b/net/ceph/auth_x.c +@@ -298,6 +298,7 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac, + return -ENOMEM; + } + au->service = th->service; ++ au->secret_id = th->secret_id; + + msg_a = au->buf->vec.iov_base; + msg_a->struct_v = 1; +@@ -555,6 +556,26 @@ static int ceph_x_create_authorizer( + return 0; + } + ++static int ceph_x_update_authorizer( ++ struct ceph_auth_client *ac, int peer_type, ++ struct ceph_auth_handshake *auth) ++{ ++ struct ceph_x_authorizer *au; ++ struct ceph_x_ticket_handler *th; ++ ++ th = get_ticket_handler(ac, peer_type); ++ if (IS_ERR(th)) ++ return PTR_ERR(th); ++ ++ au = (struct ceph_x_authorizer *)auth->authorizer; ++ if (au->secret_id < th->secret_id) { ++ dout("ceph_x_update_authorizer service %u secret %llu < %llu\n", ++ au->service, au->secret_id, th->secret_id); ++ return ceph_x_build_authorizer(ac, th, au); ++ } ++ return 0; ++} ++ + static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac, + struct ceph_authorizer *a, size_t len) + { +@@ -630,7 +651,7 @@ static void ceph_x_invalidate_authorizer(struct ceph_auth_client *ac, + + th = get_ticket_handler(ac, peer_type); + if (!IS_ERR(th)) +- remove_ticket_handler(ac, th); ++ memset(&th->validity, 0, sizeof(th->validity)); + } + + +@@ -641,6 +662,7 @@ static const struct ceph_auth_client_ops ceph_x_ops = { + .build_request = ceph_x_build_request, + .handle_reply = ceph_x_handle_reply, + .create_authorizer = ceph_x_create_authorizer, ++ .update_authorizer = ceph_x_update_authorizer, + .verify_authorizer_reply = ceph_x_verify_authorizer_reply, + .destroy_authorizer = ceph_x_destroy_authorizer, + .invalidate_authorizer = ceph_x_invalidate_authorizer, +diff --git a/net/ceph/auth_x.h b/net/ceph/auth_x.h +index e02da7a..5c2ad4e 100644 +--- a/net/ceph/auth_x.h ++++ b/net/ceph/auth_x.h +@@ -29,6 +29,7 @@ struct ceph_x_authorizer { + struct ceph_buffer *buf; + unsigned service; + u64 nonce; ++ u64 secret_id; + char reply_buf[128]; /* big enough for encrypted blob */ + }; + +diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c +index ba1037c..7f703ae 100644 +--- a/net/ceph/messenger.c ++++ b/net/ceph/messenger.c +@@ -1542,7 +1542,6 @@ static int process_connect(struct ceph_connection *con) + con->error_msg = "connect authorization failure"; + return -1; + } +- con->auth_retry = 1; + con_out_kvec_reset(con); + ret = prepare_write_connect(con); + if (ret < 0) +@@ -1627,7 +1626,7 @@ static int process_connect(struct ceph_connection *con) + + WARN_ON(con->state != CON_STATE_NEGOTIATING); + con->state = CON_STATE_OPEN; +- ++ con->auth_retry = 0; /* we authenticated; clear flag */ + con->peer_global_seq = le32_to_cpu(con->in_reply.global_seq); + con->connect_seq++; + con->peer_features = server_feat; +diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c +index 89a6409..6765da3 100644 +--- a/net/ceph/mon_client.c ++++ b/net/ceph/mon_client.c +@@ -737,7 +737,7 @@ static void delayed_work(struct work_struct *work) + + __validate_auth(monc); + +- if (monc->auth->ops->is_authenticated(monc->auth)) ++ if (ceph_auth_is_authenticated(monc->auth)) + __send_subscribe(monc); + } + __schedule_delayed(monc); +@@ -893,8 +893,7 @@ static void handle_auth_reply(struct ceph_mon_client *monc, + + mutex_lock(&monc->mutex); + had_debugfs_info = have_debugfs_info(monc); +- if (monc->auth->ops) +- was_auth = monc->auth->ops->is_authenticated(monc->auth); ++ was_auth = ceph_auth_is_authenticated(monc->auth); + monc->pending_auth = 0; + ret = ceph_handle_auth_reply(monc->auth, msg->front.iov_base, + msg->front.iov_len, +@@ -905,7 +904,7 @@ static void handle_auth_reply(struct ceph_mon_client *monc, + wake_up_all(&monc->client->auth_wq); + } else if (ret > 0) { + __send_prepared_auth_request(monc, ret); +- } else if (!was_auth && monc->auth->ops->is_authenticated(monc->auth)) { ++ } else if (!was_auth && ceph_auth_is_authenticated(monc->auth)) { + dout("authenticated, starting session\n"); + + monc->client->msgr.inst.name.type = CEPH_ENTITY_TYPE_CLIENT; +diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c +index b16dfa2..8e3aa4d 100644 +--- a/net/ceph/osd_client.c ++++ b/net/ceph/osd_client.c +@@ -671,8 +671,7 @@ static void put_osd(struct ceph_osd *osd) + if (atomic_dec_and_test(&osd->o_ref) && osd->o_auth.authorizer) { + struct ceph_auth_client *ac = osd->o_osdc->client->monc.auth; + +- if (ac->ops && ac->ops->destroy_authorizer) +- ac->ops->destroy_authorizer(ac, osd->o_auth.authorizer); ++ ceph_auth_destroy_authorizer(ac, osd->o_auth.authorizer); + kfree(osd); + } + } +@@ -1337,13 +1336,13 @@ static void kick_requests(struct ceph_osd_client *osdc, int force_resend) + __register_request(osdc, req); + __unregister_linger_request(osdc, req); + } ++ reset_changed_osds(osdc); + mutex_unlock(&osdc->request_mutex); + + if (needmap) { + dout("%d requests for down osds, need new map\n", needmap); + ceph_monc_request_next_osdmap(&osdc->client->monc); + } +- reset_changed_osds(osdc); + } + + +@@ -2127,13 +2126,17 @@ static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con, + struct ceph_auth_handshake *auth = &o->o_auth; + + if (force_new && auth->authorizer) { +- if (ac->ops && ac->ops->destroy_authorizer) +- ac->ops->destroy_authorizer(ac, auth->authorizer); ++ ceph_auth_destroy_authorizer(ac, auth->authorizer); + auth->authorizer = NULL; + } +- if (!auth->authorizer && ac->ops && ac->ops->create_authorizer) { +- int ret = ac->ops->create_authorizer(ac, CEPH_ENTITY_TYPE_OSD, +- auth); ++ if (!auth->authorizer) { ++ int ret = ceph_auth_create_authorizer(ac, CEPH_ENTITY_TYPE_OSD, ++ auth); ++ if (ret) ++ return ERR_PTR(ret); ++ } else { ++ int ret = ceph_auth_update_authorizer(ac, CEPH_ENTITY_TYPE_OSD, ++ auth); + if (ret) + return ERR_PTR(ret); + } +@@ -2149,11 +2152,7 @@ static int verify_authorizer_reply(struct ceph_connection *con, int len) + struct ceph_osd_client *osdc = o->o_osdc; + struct ceph_auth_client *ac = osdc->client->monc.auth; + +- /* +- * XXX If ac->ops or ac->ops->verify_authorizer_reply is null, +- * XXX which do we do: succeed or fail? +- */ +- return ac->ops->verify_authorizer_reply(ac, o->o_auth.authorizer, len); ++ return ceph_auth_verify_authorizer_reply(ac, o->o_auth.authorizer, len); + } + + static int invalidate_authorizer(struct ceph_connection *con) +@@ -2162,9 +2161,7 @@ static int invalidate_authorizer(struct ceph_connection *con) + struct ceph_osd_client *osdc = o->o_osdc; + struct ceph_auth_client *ac = osdc->client->monc.auth; + +- if (ac->ops && ac->ops->invalidate_authorizer) +- ac->ops->invalidate_authorizer(ac, CEPH_ENTITY_TYPE_OSD); +- ++ ceph_auth_invalidate_authorizer(ac, CEPH_ENTITY_TYPE_OSD); + return ceph_monc_validate_auth(&osdc->client->monc); + } + diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.50-51.patch b/patch/kernel/sun8i-default/0001-patch-3.4.50-51.patch new file mode 100644 index 000000000..712f0c7e6 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.50-51.patch @@ -0,0 +1,953 @@ +diff --git a/Makefile b/Makefile +index 6dd1ffb..5adfadf 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 50 ++SUBLEVEL = 51 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/tile/lib/exports.c b/arch/tile/lib/exports.c +index 2a81d32..e51e5cd 100644 +--- a/arch/tile/lib/exports.c ++++ b/arch/tile/lib/exports.c +@@ -90,4 +90,6 @@ uint64_t __ashrdi3(uint64_t, unsigned int); + EXPORT_SYMBOL(__ashrdi3); + uint64_t __ashldi3(uint64_t, unsigned int); + EXPORT_SYMBOL(__ashldi3); ++int __ffsdi2(uint64_t); ++EXPORT_SYMBOL(__ffsdi2); + #endif +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index b27b452..3663e0b 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -555,8 +555,6 @@ int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) + if (index != XCR_XFEATURE_ENABLED_MASK) + return 1; + xcr0 = xcr; +- if (kvm_x86_ops->get_cpl(vcpu) != 0) +- return 1; + if (!(xcr0 & XSTATE_FP)) + return 1; + if ((xcr0 & XSTATE_YMM) && !(xcr0 & XSTATE_SSE)) +@@ -570,7 +568,8 @@ int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) + + int kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) + { +- if (__kvm_set_xcr(vcpu, index, xcr)) { ++ if (kvm_x86_ops->get_cpl(vcpu) != 0 || ++ __kvm_set_xcr(vcpu, index, xcr)) { + kvm_inject_gp(vcpu, 0); + return 1; + } +diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c +index 7f1ea56..4c63665 100644 +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -1453,6 +1453,7 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb) + /* XXX the notifier code should handle this better */ + if (!cn->notifier_head.head) { + srcu_cleanup_notifier_head(&cn->notifier_head); ++ list_del(&cn->node); + kfree(cn); + } + +diff --git a/drivers/input/touchscreen/cyttsp_core.c b/drivers/input/touchscreen/cyttsp_core.c +index f030d9e..3f505d5 100644 +--- a/drivers/input/touchscreen/cyttsp_core.c ++++ b/drivers/input/touchscreen/cyttsp_core.c +@@ -133,7 +133,7 @@ static int cyttsp_exit_bl_mode(struct cyttsp *ts) + memcpy(bl_cmd, bl_command, sizeof(bl_command)); + if (ts->pdata->bl_keys) + memcpy(&bl_cmd[sizeof(bl_command) - CY_NUM_BL_KEYS], +- ts->pdata->bl_keys, sizeof(bl_command)); ++ ts->pdata->bl_keys, CY_NUM_BL_KEYS); + + error = ttsp_write_block_data(ts, CY_REG_BASE, + sizeof(bl_cmd), bl_cmd); +diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c +index 2e1f806..b6ed7e9 100644 +--- a/drivers/net/bonding/bond_alb.c ++++ b/drivers/net/bonding/bond_alb.c +@@ -704,6 +704,12 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond) + struct arp_pkt *arp = arp_pkt(skb); + struct slave *tx_slave = NULL; + ++ /* Don't modify or load balance ARPs that do not originate locally ++ * (e.g.,arrive via a bridge). ++ */ ++ if (!bond_slave_has_mac(bond, arp->mac_src)) ++ return NULL; ++ + if (arp->op_code == htons(ARPOP_REPLY)) { + /* the arp must be sent on the selected + * rx channel +diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h +index 4581aa5..51f1766 100644 +--- a/drivers/net/bonding/bonding.h ++++ b/drivers/net/bonding/bonding.h +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -450,6 +451,18 @@ static inline void bond_destroy_proc_dir(struct bond_net *bn) + } + #endif + ++static inline struct slave *bond_slave_has_mac(struct bonding *bond, ++ const u8 *mac) ++{ ++ int i = 0; ++ struct slave *tmp; ++ ++ bond_for_each_slave(bond, tmp, i) ++ if (!compare_ether_addr_64bits(mac, tmp->dev->dev_addr)) ++ return tmp; ++ ++ return NULL; ++} + + /* exported from bond_main.c */ + extern int bond_net_id; +diff --git a/drivers/net/ethernet/freescale/gianfar_ptp.c b/drivers/net/ethernet/freescale/gianfar_ptp.c +index ca2748a..8de54e5 100644 +--- a/drivers/net/ethernet/freescale/gianfar_ptp.c ++++ b/drivers/net/ethernet/freescale/gianfar_ptp.c +@@ -520,6 +520,7 @@ static int gianfar_ptp_probe(struct platform_device *dev) + return 0; + + no_clock: ++ iounmap(etsects->regs); + no_ioremap: + release_resource(etsects->rsrc); + no_resource: +diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c +index b3287c0..4ce981c 100644 +--- a/drivers/net/ethernet/realtek/8139cp.c ++++ b/drivers/net/ethernet/realtek/8139cp.c +@@ -1097,6 +1097,7 @@ static void cp_clean_rings (struct cp_private *cp) + cp->dev->stats.tx_dropped++; + } + } ++ netdev_reset_queue(cp->dev); + + memset(cp->rx_ring, 0, sizeof(struct cp_desc) * CP_RX_RING_SIZE); + memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE); +diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c +index cf20388..2a59e7a 100644 +--- a/drivers/net/ethernet/realtek/r8169.c ++++ b/drivers/net/ethernet/realtek/r8169.c +@@ -5126,7 +5126,20 @@ err_out: + return -EIO; + } + +-static inline void rtl8169_tso_csum(struct rtl8169_private *tp, ++static bool rtl_skb_pad(struct sk_buff *skb) ++{ ++ if (skb_padto(skb, ETH_ZLEN)) ++ return false; ++ skb_put(skb, ETH_ZLEN - skb->len); ++ return true; ++} ++ ++static bool rtl_test_hw_pad_bug(struct rtl8169_private *tp, struct sk_buff *skb) ++{ ++ return skb->len < ETH_ZLEN && tp->mac_version == RTL_GIGA_MAC_VER_34; ++} ++ ++static inline bool rtl8169_tso_csum(struct rtl8169_private *tp, + struct sk_buff *skb, u32 *opts) + { + const struct rtl_tx_desc_info *info = tx_desc_info + tp->txd_version; +@@ -5139,13 +5152,20 @@ static inline void rtl8169_tso_csum(struct rtl8169_private *tp, + } else if (skb->ip_summed == CHECKSUM_PARTIAL) { + const struct iphdr *ip = ip_hdr(skb); + ++ if (unlikely(rtl_test_hw_pad_bug(tp, skb))) ++ return skb_checksum_help(skb) == 0 && rtl_skb_pad(skb); ++ + if (ip->protocol == IPPROTO_TCP) + opts[offset] |= info->checksum.tcp; + else if (ip->protocol == IPPROTO_UDP) + opts[offset] |= info->checksum.udp; + else + WARN_ON_ONCE(1); ++ } else { ++ if (unlikely(rtl_test_hw_pad_bug(tp, skb))) ++ return rtl_skb_pad(skb); + } ++ return true; + } + + static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, +@@ -5166,17 +5186,15 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, + goto err_stop_0; + } + +- /* 8168evl does not automatically pad to minimum length. */ +- if (unlikely(tp->mac_version == RTL_GIGA_MAC_VER_34 && +- skb->len < ETH_ZLEN)) { +- if (skb_padto(skb, ETH_ZLEN)) +- goto err_update_stats; +- skb_put(skb, ETH_ZLEN - skb->len); +- } +- + if (unlikely(le32_to_cpu(txd->opts1) & DescOwn)) + goto err_stop_0; + ++ opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb)); ++ opts[0] = DescOwn; ++ ++ if (!rtl8169_tso_csum(tp, skb, opts)) ++ goto err_update_stats; ++ + len = skb_headlen(skb); + mapping = dma_map_single(d, skb->data, len, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(d, mapping))) { +@@ -5188,11 +5206,6 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, + tp->tx_skb[entry].len = len; + txd->addr = cpu_to_le64(mapping); + +- opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb)); +- opts[0] = DescOwn; +- +- rtl8169_tso_csum(tp, skb, opts); +- + frags = rtl8169_xmit_frags(tp, skb, opts); + if (frags < 0) + goto err_dma_1; +diff --git a/drivers/net/team/team_mode_roundrobin.c b/drivers/net/team/team_mode_roundrobin.c +index a0e8f80..bf6a818 100644 +--- a/drivers/net/team/team_mode_roundrobin.c ++++ b/drivers/net/team/team_mode_roundrobin.c +@@ -52,6 +52,8 @@ static bool rr_transmit(struct team *team, struct sk_buff *skb) + + port_index = rr_priv(team)->sent_packets++ % team->port_count; + port = team_get_port_by_index_rcu(team, port_index); ++ if (unlikely(!port)) ++ goto drop; + port = __get_first_port_up(team, port); + if (unlikely(!port)) + goto drop; +diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c +index 1ab0560..a7c4324 100644 +--- a/drivers/target/iscsi/iscsi_target_erl0.c ++++ b/drivers/target/iscsi/iscsi_target_erl0.c +@@ -831,11 +831,11 @@ extern int iscsit_stop_time2retain_timer(struct iscsi_session *sess) + return 0; + + sess->time2retain_timer_flags |= ISCSI_TF_STOP; +- spin_unlock_bh(&se_tpg->session_lock); ++ spin_unlock(&se_tpg->session_lock); + + del_timer_sync(&sess->time2retain_timer); + +- spin_lock_bh(&se_tpg->session_lock); ++ spin_lock(&se_tpg->session_lock); + sess->time2retain_timer_flags &= ~ISCSI_TF_RUNNING; + pr_debug("Stopped Time2Retain Timer for SID: %u\n", + sess->sid); +diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c +index 3377437..a39a08c 100644 +--- a/drivers/usb/serial/ti_usb_3410_5052.c ++++ b/drivers/usb/serial/ti_usb_3410_5052.c +@@ -179,7 +179,8 @@ static struct usb_device_id ti_id_table_3410[15+TI_EXTRA_VID_PID_COUNT+1] = { + { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, + { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) }, + { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) }, +- { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) }, ++ { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STEREO_PLUG_ID) }, ++ { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) }, + { USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) }, + }; + +diff --git a/drivers/usb/serial/ti_usb_3410_5052.h b/drivers/usb/serial/ti_usb_3410_5052.h +index b353e7e..4a2423e 100644 +--- a/drivers/usb/serial/ti_usb_3410_5052.h ++++ b/drivers/usb/serial/ti_usb_3410_5052.h +@@ -52,7 +52,9 @@ + + /* Abbott Diabetics vendor and product ids */ + #define ABBOTT_VENDOR_ID 0x1a61 +-#define ABBOTT_PRODUCT_ID 0x3410 ++#define ABBOTT_STEREO_PLUG_ID 0x3410 ++#define ABBOTT_PRODUCT_ID ABBOTT_STEREO_PLUG_ID ++#define ABBOTT_STRIP_PORT_ID 0x3420 + + /* Commands */ + #define TI_GET_VERSION 0x01 +diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c +index 6f292dd..f255d37 100644 +--- a/fs/notify/inotify/inotify_user.c ++++ b/fs/notify/inotify/inotify_user.c +@@ -577,7 +577,6 @@ static int inotify_update_existing_watch(struct fsnotify_group *group, + int add = (arg & IN_MASK_ADD); + int ret; + +- /* don't allow invalid bits: we don't want flags set */ + mask = inotify_arg_to_mask(arg); + + fsn_mark = fsnotify_find_inode_mark(group, inode); +@@ -628,7 +627,6 @@ static int inotify_new_watch(struct fsnotify_group *group, + struct idr *idr = &group->inotify_data.idr; + spinlock_t *idr_lock = &group->inotify_data.idr_lock; + +- /* don't allow invalid bits: we don't want flags set */ + mask = inotify_arg_to_mask(arg); + + tmp_i_mark = kmem_cache_alloc(inotify_inode_mark_cachep, GFP_KERNEL); +@@ -757,6 +755,10 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname, + int ret, fput_needed; + unsigned flags = 0; + ++ /* don't allow invalid bits: we don't want flags set */ ++ if (unlikely(!(mask & ALL_INOTIFY_BITS))) ++ return -EINVAL; ++ + filp = fget_light(fd, &fput_needed); + if (unlikely(!filp)) + return -EBADF; +diff --git a/include/linux/rculist_nulls.h b/include/linux/rculist_nulls.h +index 2ae1371..1c33dd7 100644 +--- a/include/linux/rculist_nulls.h ++++ b/include/linux/rculist_nulls.h +@@ -105,9 +105,14 @@ static inline void hlist_nulls_add_head_rcu(struct hlist_nulls_node *n, + * @head: the head for your list. + * @member: the name of the hlist_nulls_node within the struct. + * ++ * The barrier() is needed to make sure compiler doesn't cache first element [1], ++ * as this loop can be restarted [2] ++ * [1] Documentation/atomic_ops.txt around line 114 ++ * [2] Documentation/RCU/rculist_nulls.txt around line 146 + */ + #define hlist_nulls_for_each_entry_rcu(tpos, pos, head, member) \ +- for (pos = rcu_dereference_raw(hlist_nulls_first_rcu(head)); \ ++ for (({barrier();}), \ ++ pos = rcu_dereference_raw(hlist_nulls_first_rcu(head)); \ + (!is_a_nulls(pos)) && \ + ({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1; }); \ + pos = rcu_dereference_raw(hlist_nulls_next_rcu(pos))) +diff --git a/include/linux/socket.h b/include/linux/socket.h +index 8f15b1d..9b54ebe 100644 +--- a/include/linux/socket.h ++++ b/include/linux/socket.h +@@ -336,6 +336,9 @@ extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data); + + struct timespec; + ++/* The __sys_...msg variants allow MSG_CMSG_COMPAT */ ++extern long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags); ++extern long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags); + extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, + unsigned int flags, struct timespec *timeout); + extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, +diff --git a/net/compat.c b/net/compat.c +index ae6d67a..014e1c7 100644 +--- a/net/compat.c ++++ b/net/compat.c +@@ -743,19 +743,25 @@ static unsigned char nas[21] = { + + asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, unsigned flags) + { +- return sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); ++ if (flags & MSG_CMSG_COMPAT) ++ return -EINVAL; ++ return __sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); + } + + asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg, + unsigned vlen, unsigned int flags) + { ++ if (flags & MSG_CMSG_COMPAT) ++ return -EINVAL; + return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, + flags | MSG_CMSG_COMPAT); + } + + asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags) + { +- return sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); ++ if (flags & MSG_CMSG_COMPAT) ++ return -EINVAL; ++ return __sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); + } + + asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len, unsigned flags) +@@ -777,6 +783,9 @@ asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg, + int datagrams; + struct timespec ktspec; + ++ if (flags & MSG_CMSG_COMPAT) ++ return -EINVAL; ++ + if (COMPAT_USE_64BIT_TIME) + return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, + flags | MSG_CMSG_COMPAT, +diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c +index b57532d..a16509c 100644 +--- a/net/ipv4/ip_gre.c ++++ b/net/ipv4/ip_gre.c +@@ -722,6 +722,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev + tiph = &tunnel->parms.iph; + } + ++ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); + if ((dst = tiph->daddr) == 0) { + /* NBMA tunnel */ + +@@ -865,7 +866,6 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev + skb_reset_transport_header(skb); + skb_push(skb, gre_hlen); + skb_reset_network_header(skb); +- memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); + IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | + IPSKB_REROUTED); + skb_dst_drop(skb); +diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c +index ae1413e..d2f6348 100644 +--- a/net/ipv4/ipip.c ++++ b/net/ipv4/ipip.c +@@ -448,6 +448,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) + if (tos & 1) + tos = old_iph->tos; + ++ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); + if (!dst) { + /* NBMA tunnel */ + if ((rt = skb_rtable(skb)) == NULL) { +@@ -530,7 +531,6 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) + skb->transport_header = skb->network_header; + skb_push(skb, sizeof(struct iphdr)); + skb_reset_network_header(skb); +- memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); + IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | + IPSKB_REROUTED); + skb_dst_drop(skb); +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index dcb19f5..0b91c30 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -3055,8 +3055,11 @@ int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *hp, + + for (i = 0; i < shi->nr_frags; ++i) { + const struct skb_frag_struct *f = &shi->frags[i]; +- struct page *page = skb_frag_page(f); +- sg_set_page(&sg, page, skb_frag_size(f), f->page_offset); ++ unsigned int offset = f->page_offset; ++ struct page *page = skb_frag_page(f) + (offset >> PAGE_SHIFT); ++ ++ sg_set_page(&sg, page, skb_frag_size(f), ++ offset_in_page(offset)); + if (crypto_hash_update(desc, &sg, skb_frag_size(f))) + return 1; + } +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index 762c78f..55d96c3 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -3038,8 +3038,8 @@ static void tcp_update_cwnd_in_recovery(struct sock *sk, int newly_acked_sacked, + * tcp_xmit_retransmit_queue(). + */ + static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, +- int prior_sacked, bool is_dupack, +- int flag) ++ int prior_sacked, int prior_packets, ++ bool is_dupack, int flag) + { + struct inet_connection_sock *icsk = inet_csk(sk); + struct tcp_sock *tp = tcp_sk(sk); +@@ -3105,7 +3105,8 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, + tcp_add_reno_sack(sk); + } else + do_lost = tcp_try_undo_partial(sk, pkts_acked); +- newly_acked_sacked = pkts_acked + tp->sacked_out - prior_sacked; ++ newly_acked_sacked = prior_packets - tp->packets_out + ++ tp->sacked_out - prior_sacked; + break; + case TCP_CA_Loss: + if (flag & FLAG_DATA_ACKED) +@@ -3127,7 +3128,8 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, + if (is_dupack) + tcp_add_reno_sack(sk); + } +- newly_acked_sacked = pkts_acked + tp->sacked_out - prior_sacked; ++ newly_acked_sacked = prior_packets - tp->packets_out + ++ tp->sacked_out - prior_sacked; + + if (icsk->icsk_ca_state <= TCP_CA_Disorder) + tcp_try_undo_dsack(sk); +@@ -3740,9 +3742,10 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) + bool is_dupack = false; + u32 prior_in_flight; + u32 prior_fackets; +- int prior_packets; ++ int prior_packets = tp->packets_out; + int prior_sacked = tp->sacked_out; + int pkts_acked = 0; ++ int previous_packets_out = 0; + int frto_cwnd = 0; + + /* If the ack is older than previous acks +@@ -3819,14 +3822,14 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) + sk->sk_err_soft = 0; + icsk->icsk_probes_out = 0; + tp->rcv_tstamp = tcp_time_stamp; +- prior_packets = tp->packets_out; + if (!prior_packets) + goto no_queue; + + /* See if we can take anything off of the retransmit queue. */ ++ previous_packets_out = tp->packets_out; + flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una); + +- pkts_acked = prior_packets - tp->packets_out; ++ pkts_acked = previous_packets_out - tp->packets_out; + + if (tp->frto_counter) + frto_cwnd = tcp_process_frto(sk, flag); +@@ -3841,7 +3844,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) + tcp_cong_avoid(sk, ack, prior_in_flight); + is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP)); + tcp_fastretrans_alert(sk, pkts_acked, prior_sacked, +- is_dupack, flag); ++ prior_packets, is_dupack, flag); + } else { + if ((flag & FLAG_DATA_ACKED) && !frto_cwnd) + tcp_cong_avoid(sk, ack, prior_in_flight); +@@ -3856,7 +3859,7 @@ no_queue: + /* If data was DSACKed, see if we can undo a cwnd reduction. */ + if (flag & FLAG_DSACKING_ACK) + tcp_fastretrans_alert(sk, pkts_acked, prior_sacked, +- is_dupack, flag); ++ prior_packets, is_dupack, flag); + /* If this ack opens up a zero window, clear backoff. It was + * being used to time the probes, and is probably far higher than + * it needs to be for normal retransmission. +@@ -3876,7 +3879,7 @@ old_ack: + if (TCP_SKB_CB(skb)->sacked) { + flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una); + tcp_fastretrans_alert(sk, pkts_acked, prior_sacked, +- is_dupack, flag); ++ prior_packets, is_dupack, flag); + } + + SOCK_DEBUG(sk, "Ack %u before %u:%u\n", ack, tp->snd_una, tp->snd_nxt); +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c +index 9db21e3..12999a3 100644 +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -835,11 +835,13 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, + &md5); + tcp_header_size = tcp_options_size + sizeof(struct tcphdr); + +- if (tcp_packets_in_flight(tp) == 0) { ++ if (tcp_packets_in_flight(tp) == 0) + tcp_ca_event(sk, CA_EVENT_TX_START); +- skb->ooo_okay = 1; +- } else +- skb->ooo_okay = 0; ++ ++ /* if no packet is in qdisc/device queue, then allow XPS to select ++ * another queue. ++ */ ++ skb->ooo_okay = sk_wmem_alloc_get(sk) == 0; + + skb_push(skb, tcp_header_size); + skb_reset_transport_header(skb); +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index 2c496d6..f4fe3c0 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -2432,8 +2432,10 @@ static void init_loopback(struct net_device *dev) + sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); + + /* Failure cases are ignored */ +- if (!IS_ERR(sp_rt)) ++ if (!IS_ERR(sp_rt)) { ++ sp_ifa->rt = sp_rt; + ip6_ins_rt(sp_rt); ++ } + } + read_unlock_bh(&idev->lock); + } +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index ce661ba..bf290ce 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -1236,7 +1236,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, + if (WARN_ON(np->cork.opt)) + return -EINVAL; + +- np->cork.opt = kmalloc(opt->tot_len, sk->sk_allocation); ++ np->cork.opt = kzalloc(opt->tot_len, sk->sk_allocation); + if (unlikely(np->cork.opt == NULL)) + return -ENOBUFS; + +diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c +index 9728a75..c6dee80 100644 +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -350,19 +350,19 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh + skb_put(skb, 2); + + /* Copy user data into skb */ +- error = memcpy_fromiovec(skb->data, m->msg_iov, total_len); ++ error = memcpy_fromiovec(skb_put(skb, total_len), m->msg_iov, ++ total_len); + if (error < 0) { + kfree_skb(skb); + goto error_put_sess_tun; + } +- skb_put(skb, total_len); + + l2tp_xmit_skb(session, skb, session->hdr_len); + + sock_put(ps->tunnel_sock); + sock_put(sk); + +- return error; ++ return total_len; + + error_put_sess_tun: + sock_put(ps->tunnel_sock); +diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c +index d8d4243..6bb1d42 100644 +--- a/net/netlabel/netlabel_domainhash.c ++++ b/net/netlabel/netlabel_domainhash.c +@@ -245,6 +245,71 @@ static void netlbl_domhsh_audit_add(struct netlbl_dom_map *entry, + } + } + ++/** ++ * netlbl_domhsh_validate - Validate a new domain mapping entry ++ * @entry: the entry to validate ++ * ++ * This function validates the new domain mapping entry to ensure that it is ++ * a valid entry. Returns zero on success, negative values on failure. ++ * ++ */ ++static int netlbl_domhsh_validate(const struct netlbl_dom_map *entry) ++{ ++ struct netlbl_af4list *iter4; ++ struct netlbl_domaddr4_map *map4; ++#if IS_ENABLED(CONFIG_IPV6) ++ struct netlbl_af6list *iter6; ++ struct netlbl_domaddr6_map *map6; ++#endif /* IPv6 */ ++ ++ if (entry == NULL) ++ return -EINVAL; ++ ++ switch (entry->type) { ++ case NETLBL_NLTYPE_UNLABELED: ++ if (entry->type_def.cipsov4 != NULL || ++ entry->type_def.addrsel != NULL) ++ return -EINVAL; ++ break; ++ case NETLBL_NLTYPE_CIPSOV4: ++ if (entry->type_def.cipsov4 == NULL) ++ return -EINVAL; ++ break; ++ case NETLBL_NLTYPE_ADDRSELECT: ++ netlbl_af4list_foreach(iter4, &entry->type_def.addrsel->list4) { ++ map4 = netlbl_domhsh_addr4_entry(iter4); ++ switch (map4->type) { ++ case NETLBL_NLTYPE_UNLABELED: ++ if (map4->type_def.cipsov4 != NULL) ++ return -EINVAL; ++ break; ++ case NETLBL_NLTYPE_CIPSOV4: ++ if (map4->type_def.cipsov4 == NULL) ++ return -EINVAL; ++ break; ++ default: ++ return -EINVAL; ++ } ++ } ++#if IS_ENABLED(CONFIG_IPV6) ++ netlbl_af6list_foreach(iter6, &entry->type_def.addrsel->list6) { ++ map6 = netlbl_domhsh_addr6_entry(iter6); ++ switch (map6->type) { ++ case NETLBL_NLTYPE_UNLABELED: ++ break; ++ default: ++ return -EINVAL; ++ } ++ } ++#endif /* IPv6 */ ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ + /* + * Domain Hash Table Functions + */ +@@ -311,6 +376,10 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, + struct netlbl_af6list *tmp6; + #endif /* IPv6 */ + ++ ret_val = netlbl_domhsh_validate(entry); ++ if (ret_val != 0) ++ return ret_val; ++ + /* XXX - we can remove this RCU read lock as the spinlock protects the + * entire function, but before we do we need to fixup the + * netlbl_af[4,6]list RCU functions to do "the right thing" with +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index cfcd783..8ed5d93 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -2848,12 +2848,11 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr, + return -EOPNOTSUPP; + + uaddr->sa_family = AF_PACKET; ++ memset(uaddr->sa_data, 0, sizeof(uaddr->sa_data)); + rcu_read_lock(); + dev = dev_get_by_index_rcu(sock_net(sk), pkt_sk(sk)->ifindex); + if (dev) +- strncpy(uaddr->sa_data, dev->name, 14); +- else +- memset(uaddr->sa_data, 0, 14); ++ strlcpy(uaddr->sa_data, dev->name, sizeof(uaddr->sa_data)); + rcu_read_unlock(); + *uaddr_len = sizeof(*uaddr); + +diff --git a/net/sctp/socket.c b/net/sctp/socket.c +index 9fd05ed..4bc6e0b 100644 +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -3929,6 +3929,12 @@ SCTP_STATIC void sctp_destroy_sock(struct sock *sk) + + /* Release our hold on the endpoint. */ + sp = sctp_sk(sk); ++ /* This could happen during socket init, thus we bail out ++ * early, since the rest of the below is not setup either. ++ */ ++ if (sp->ep == NULL) ++ return; ++ + if (sp->do_auto_asconf) { + sp->do_auto_asconf = 0; + list_del(&sp->auto_asconf_list); +diff --git a/net/socket.c b/net/socket.c +index dab3176..47ce3ea 100644 +--- a/net/socket.c ++++ b/net/socket.c +@@ -1899,9 +1899,9 @@ struct used_address { + unsigned int name_len; + }; + +-static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, +- struct msghdr *msg_sys, unsigned flags, +- struct used_address *used_address) ++static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg, ++ struct msghdr *msg_sys, unsigned flags, ++ struct used_address *used_address) + { + struct compat_msghdr __user *msg_compat = + (struct compat_msghdr __user *)msg; +@@ -2017,22 +2017,30 @@ out: + * BSD sendmsg interface + */ + +-SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags) ++long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags) + { + int fput_needed, err; + struct msghdr msg_sys; +- struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed); ++ struct socket *sock; + ++ sock = sockfd_lookup_light(fd, &err, &fput_needed); + if (!sock) + goto out; + +- err = __sys_sendmsg(sock, msg, &msg_sys, flags, NULL); ++ err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL); + + fput_light(sock->file, fput_needed); + out: + return err; + } + ++SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags) ++{ ++ if (flags & MSG_CMSG_COMPAT) ++ return -EINVAL; ++ return __sys_sendmsg(fd, msg, flags); ++} ++ + /* + * Linux sendmmsg interface + */ +@@ -2063,15 +2071,16 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, + + while (datagrams < vlen) { + if (MSG_CMSG_COMPAT & flags) { +- err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry, +- &msg_sys, flags, &used_address); ++ err = ___sys_sendmsg(sock, (struct msghdr __user *)compat_entry, ++ &msg_sys, flags, &used_address); + if (err < 0) + break; + err = __put_user(err, &compat_entry->msg_len); + ++compat_entry; + } else { +- err = __sys_sendmsg(sock, (struct msghdr __user *)entry, +- &msg_sys, flags, &used_address); ++ err = ___sys_sendmsg(sock, ++ (struct msghdr __user *)entry, ++ &msg_sys, flags, &used_address); + if (err < 0) + break; + err = put_user(err, &entry->msg_len); +@@ -2095,11 +2104,13 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, + SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg, + unsigned int, vlen, unsigned int, flags) + { ++ if (flags & MSG_CMSG_COMPAT) ++ return -EINVAL; + return __sys_sendmmsg(fd, mmsg, vlen, flags); + } + +-static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg, +- struct msghdr *msg_sys, unsigned flags, int nosec) ++static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, ++ struct msghdr *msg_sys, unsigned flags, int nosec) + { + struct compat_msghdr __user *msg_compat = + (struct compat_msghdr __user *)msg; +@@ -2192,23 +2203,31 @@ out: + * BSD recvmsg interface + */ + +-SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg, +- unsigned int, flags) ++long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags) + { + int fput_needed, err; + struct msghdr msg_sys; +- struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed); ++ struct socket *sock; + ++ sock = sockfd_lookup_light(fd, &err, &fput_needed); + if (!sock) + goto out; + +- err = __sys_recvmsg(sock, msg, &msg_sys, flags, 0); ++ err = ___sys_recvmsg(sock, msg, &msg_sys, flags, 0); + + fput_light(sock->file, fput_needed); + out: + return err; + } + ++SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg, ++ unsigned int, flags) ++{ ++ if (flags & MSG_CMSG_COMPAT) ++ return -EINVAL; ++ return __sys_recvmsg(fd, msg, flags); ++} ++ + /* + * Linux recvmmsg interface + */ +@@ -2246,17 +2265,18 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, + * No need to ask LSM for more than the first datagram. + */ + if (MSG_CMSG_COMPAT & flags) { +- err = __sys_recvmsg(sock, (struct msghdr __user *)compat_entry, +- &msg_sys, flags & ~MSG_WAITFORONE, +- datagrams); ++ err = ___sys_recvmsg(sock, (struct msghdr __user *)compat_entry, ++ &msg_sys, flags & ~MSG_WAITFORONE, ++ datagrams); + if (err < 0) + break; + err = __put_user(err, &compat_entry->msg_len); + ++compat_entry; + } else { +- err = __sys_recvmsg(sock, (struct msghdr __user *)entry, +- &msg_sys, flags & ~MSG_WAITFORONE, +- datagrams); ++ err = ___sys_recvmsg(sock, ++ (struct msghdr __user *)entry, ++ &msg_sys, flags & ~MSG_WAITFORONE, ++ datagrams); + if (err < 0) + break; + err = put_user(err, &entry->msg_len); +@@ -2323,6 +2343,9 @@ SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg, + int datagrams; + struct timespec timeout_sys; + ++ if (flags & MSG_CMSG_COMPAT) ++ return -EINVAL; ++ + if (!timeout) + return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL); + +diff --git a/sound/usb/card.c b/sound/usb/card.c +index b41730d..658ea11 100644 +--- a/sound/usb/card.c ++++ b/sound/usb/card.c +@@ -149,14 +149,32 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int + return -EINVAL; + } + ++ alts = &iface->altsetting[0]; ++ altsd = get_iface_desc(alts); ++ ++ /* ++ * Android with both accessory and audio interfaces enabled gets the ++ * interface numbers wrong. ++ */ ++ if ((chip->usb_id == USB_ID(0x18d1, 0x2d04) || ++ chip->usb_id == USB_ID(0x18d1, 0x2d05)) && ++ interface == 0 && ++ altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC && ++ altsd->bInterfaceSubClass == USB_SUBCLASS_VENDOR_SPEC) { ++ interface = 2; ++ iface = usb_ifnum_to_if(dev, interface); ++ if (!iface) ++ return -EINVAL; ++ alts = &iface->altsetting[0]; ++ altsd = get_iface_desc(alts); ++ } ++ + if (usb_interface_claimed(iface)) { + snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n", + dev->devnum, ctrlif, interface); + return -EINVAL; + } + +- alts = &iface->altsetting[0]; +- altsd = get_iface_desc(alts); + if ((altsd->bInterfaceClass == USB_CLASS_AUDIO || + altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) && + altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) { +diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c +index e075a67..5ca4652 100644 +--- a/sound/usb/mixer.c ++++ b/sound/usb/mixer.c +@@ -821,6 +821,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, + + case USB_ID(0x046d, 0x0808): + case USB_ID(0x046d, 0x0809): ++ case USB_ID(0x046d, 0x081b): /* HD Webcam c310 */ + case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */ + case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */ + case USB_ID(0x046d, 0x0991): diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.51-52.patch b/patch/kernel/sun8i-default/0001-patch-3.4.51-52.patch new file mode 100644 index 000000000..b866ed867 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.51-52.patch @@ -0,0 +1,791 @@ +diff --git a/Makefile b/Makefile +index 5adfadf..810572b 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 51 ++SUBLEVEL = 52 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h +index 42dec04..0a5e8a5 100644 +--- a/arch/arm/include/asm/cacheflush.h ++++ b/arch/arm/include/asm/cacheflush.h +@@ -305,9 +305,7 @@ static inline void flush_anon_page(struct vm_area_struct *vma, + } + + #define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE +-static inline void flush_kernel_dcache_page(struct page *page) +-{ +-} ++extern void flush_kernel_dcache_page(struct page *); + + #define flush_dcache_mmap_lock(mapping) \ + spin_lock_irq(&(mapping)->tree_lock) +diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c +index 40ca11e..8f0d285 100644 +--- a/arch/arm/mm/flush.c ++++ b/arch/arm/mm/flush.c +@@ -299,6 +299,39 @@ void flush_dcache_page(struct page *page) + EXPORT_SYMBOL(flush_dcache_page); + + /* ++ * Ensure cache coherency for the kernel mapping of this page. We can ++ * assume that the page is pinned via kmap. ++ * ++ * If the page only exists in the page cache and there are no user ++ * space mappings, this is a no-op since the page was already marked ++ * dirty at creation. Otherwise, we need to flush the dirty kernel ++ * cache lines directly. ++ */ ++void flush_kernel_dcache_page(struct page *page) ++{ ++ if (cache_is_vivt() || cache_is_vipt_aliasing()) { ++ struct address_space *mapping; ++ ++ mapping = page_mapping(page); ++ ++ if (!mapping || mapping_mapped(mapping)) { ++ void *addr; ++ ++ addr = page_address(page); ++ /* ++ * kmap_atomic() doesn't set the page virtual ++ * address for highmem pages, and ++ * kunmap_atomic() takes care of cache ++ * flushing already. ++ */ ++ if (!IS_ENABLED(CONFIG_HIGHMEM) || addr) ++ __cpuc_flush_dcache_area(addr, PAGE_SIZE); ++ } ++ } ++} ++EXPORT_SYMBOL(flush_kernel_dcache_page); ++ ++/* + * Flush an anonymous page so that users of get_user_pages() + * can safely access the data. The expected sequence is: + * +diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c +index d51225f..eb5293a 100644 +--- a/arch/arm/mm/nommu.c ++++ b/arch/arm/mm/nommu.c +@@ -57,6 +57,12 @@ void flush_dcache_page(struct page *page) + } + EXPORT_SYMBOL(flush_dcache_page); + ++void flush_kernel_dcache_page(struct page *page) ++{ ++ __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE); ++} ++EXPORT_SYMBOL(flush_kernel_dcache_page); ++ + void copy_to_user_page(struct vm_area_struct *vma, struct page *page, + unsigned long uaddr, void *dst, const void *src, + unsigned long len) +diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c +index 147614e..6a8a382 100644 +--- a/drivers/net/wan/dlci.c ++++ b/drivers/net/wan/dlci.c +@@ -384,21 +384,37 @@ static int dlci_del(struct dlci_add *dlci) + struct frad_local *flp; + struct net_device *master, *slave; + int err; ++ bool found = false; ++ ++ rtnl_lock(); + + /* validate slave device */ + master = __dev_get_by_name(&init_net, dlci->devname); +- if (!master) +- return -ENODEV; ++ if (!master) { ++ err = -ENODEV; ++ goto out; ++ } ++ ++ list_for_each_entry(dlp, &dlci_devs, list) { ++ if (dlp->master == master) { ++ found = true; ++ break; ++ } ++ } ++ if (!found) { ++ err = -ENODEV; ++ goto out; ++ } + + if (netif_running(master)) { +- return -EBUSY; ++ err = -EBUSY; ++ goto out; + } + + dlp = netdev_priv(master); + slave = dlp->slave; + flp = netdev_priv(slave); + +- rtnl_lock(); + err = (*flp->deassoc)(slave, master); + if (!err) { + list_del(&dlp->list); +@@ -407,8 +423,8 @@ static int dlci_del(struct dlci_add *dlci) + + dev_put(slave); + } ++out: + rtnl_unlock(); +- + return err; + } + +diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c +index 7d47514..2e99f79 100644 +--- a/drivers/tty/serial/pch_uart.c ++++ b/drivers/tty/serial/pch_uart.c +@@ -1034,22 +1034,37 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv) + static void pch_uart_err_ir(struct eg20t_port *priv, unsigned int lsr) + { + u8 fcr = ioread8(priv->membase + UART_FCR); ++ struct uart_port *port = &priv->port; ++ struct tty_struct *tty = tty_port_tty_get(&port->state->port); ++ char *error_msg[5] = {}; ++ int i = 0; + + /* Reset FIFO */ + fcr |= UART_FCR_CLEAR_RCVR; + iowrite8(fcr, priv->membase + UART_FCR); + + if (lsr & PCH_UART_LSR_ERR) +- dev_err(&priv->pdev->dev, "Error data in FIFO\n"); ++ error_msg[i++] = "Error data in FIFO\n"; + +- if (lsr & UART_LSR_FE) +- dev_err(&priv->pdev->dev, "Framing Error\n"); ++ if (lsr & UART_LSR_FE) { ++ port->icount.frame++; ++ error_msg[i++] = " Framing Error\n"; ++ } + +- if (lsr & UART_LSR_PE) +- dev_err(&priv->pdev->dev, "Parity Error\n"); ++ if (lsr & UART_LSR_PE) { ++ port->icount.parity++; ++ error_msg[i++] = " Parity Error\n"; ++ } + +- if (lsr & UART_LSR_OE) +- dev_err(&priv->pdev->dev, "Overrun Error\n"); ++ if (lsr & UART_LSR_OE) { ++ port->icount.overrun++; ++ error_msg[i++] = " Overrun Error\n"; ++ } ++ ++ if (tty == NULL) { ++ for (i = 0; error_msg[i] != NULL; i++) ++ dev_err(&priv->pdev->dev, error_msg[i]); ++ } + } + + static irqreturn_t pch_uart_interrupt(int irq, void *dev_id) +diff --git a/fs/exec.c b/fs/exec.c +index 2b7f5ff..0ea0b4c 100644 +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -1163,13 +1163,6 @@ void setup_new_exec(struct linux_binprm * bprm) + set_dumpable(current->mm, suid_dumpable); + } + +- /* +- * Flush performance counters when crossing a +- * security domain: +- */ +- if (!get_dumpable(current->mm)) +- perf_event_exit_task(current); +- + /* An exec changes our domain. We are no longer part of the thread + group */ + +@@ -1233,6 +1226,15 @@ void install_exec_creds(struct linux_binprm *bprm) + + commit_creds(bprm->cred); + bprm->cred = NULL; ++ ++ /* ++ * Disable monitoring for regular users ++ * when executing setuid binaries. Must ++ * wait until new credentials are committed ++ * by commit_creds() above ++ */ ++ if (get_dumpable(current->mm) != SUID_DUMP_USER) ++ perf_event_exit_task(current); + /* + * cred_guard_mutex must be held at least to this point to prevent + * ptrace_attach() from altering our determination of the task's +diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c +index 8640a12..25c472b 100644 +--- a/fs/ubifs/dir.c ++++ b/fs/ubifs/dir.c +@@ -357,31 +357,50 @@ static unsigned int vfs_dent_type(uint8_t type) + static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) + { + int err, over = 0; ++ loff_t pos = file->f_pos; + struct qstr nm; + union ubifs_key key; + struct ubifs_dent_node *dent; + struct inode *dir = file->f_path.dentry->d_inode; + struct ubifs_info *c = dir->i_sb->s_fs_info; + +- dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, file->f_pos); ++ dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, pos); + +- if (file->f_pos > UBIFS_S_KEY_HASH_MASK || file->f_pos == 2) ++ if (pos > UBIFS_S_KEY_HASH_MASK || pos == 2) + /* + * The directory was seek'ed to a senseless position or there + * are no more entries. + */ + return 0; + ++ if (file->f_version == 0) { ++ /* ++ * The file was seek'ed, which means that @file->private_data ++ * is now invalid. This may also be just the first ++ * 'ubifs_readdir()' invocation, in which case ++ * @file->private_data is NULL, and the below code is ++ * basically a no-op. ++ */ ++ kfree(file->private_data); ++ file->private_data = NULL; ++ } ++ ++ /* ++ * 'generic_file_llseek()' unconditionally sets @file->f_version to ++ * zero, and we use this for detecting whether the file was seek'ed. ++ */ ++ file->f_version = 1; ++ + /* File positions 0 and 1 correspond to "." and ".." */ +- if (file->f_pos == 0) { ++ if (pos == 0) { + ubifs_assert(!file->private_data); + over = filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR); + if (over) + return 0; +- file->f_pos = 1; ++ file->f_pos = pos = 1; + } + +- if (file->f_pos == 1) { ++ if (pos == 1) { + ubifs_assert(!file->private_data); + over = filldir(dirent, "..", 2, 1, + parent_ino(file->f_path.dentry), DT_DIR); +@@ -397,7 +416,7 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) + goto out; + } + +- file->f_pos = key_hash_flash(c, &dent->key); ++ file->f_pos = pos = key_hash_flash(c, &dent->key); + file->private_data = dent; + } + +@@ -405,17 +424,16 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) + if (!dent) { + /* + * The directory was seek'ed to and is now readdir'ed. +- * Find the entry corresponding to @file->f_pos or the +- * closest one. ++ * Find the entry corresponding to @pos or the closest one. + */ +- dent_key_init_hash(c, &key, dir->i_ino, file->f_pos); ++ dent_key_init_hash(c, &key, dir->i_ino, pos); + nm.name = NULL; + dent = ubifs_tnc_next_ent(c, &key, &nm); + if (IS_ERR(dent)) { + err = PTR_ERR(dent); + goto out; + } +- file->f_pos = key_hash_flash(c, &dent->key); ++ file->f_pos = pos = key_hash_flash(c, &dent->key); + file->private_data = dent; + } + +@@ -427,7 +445,7 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) + ubifs_inode(dir)->creat_sqnum); + + nm.len = le16_to_cpu(dent->nlen); +- over = filldir(dirent, dent->name, nm.len, file->f_pos, ++ over = filldir(dirent, dent->name, nm.len, pos, + le64_to_cpu(dent->inum), + vfs_dent_type(dent->type)); + if (over) +@@ -443,9 +461,17 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) + } + + kfree(file->private_data); +- file->f_pos = key_hash_flash(c, &dent->key); ++ file->f_pos = pos = key_hash_flash(c, &dent->key); + file->private_data = dent; + cond_resched(); ++ ++ if (file->f_version == 0) ++ /* ++ * The file was seek'ed meanwhile, lets return and start ++ * reading direntries from the new position on the next ++ * invocation. ++ */ ++ return 0; + } + + out: +@@ -456,15 +482,13 @@ out: + + kfree(file->private_data); + file->private_data = NULL; ++ /* 2 is a special value indicating that there are no more direntries */ + file->f_pos = 2; + return 0; + } + +-/* If a directory is seeked, we have to free saved readdir() state */ + static loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int origin) + { +- kfree(file->private_data); +- file->private_data = NULL; + return generic_file_llseek(file, offset, origin); + } + +diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h +index 8e9a069..89fb74e 100644 +--- a/include/linux/perf_event.h ++++ b/include/linux/perf_event.h +@@ -950,8 +950,7 @@ struct perf_event { + /* mmap bits */ + struct mutex mmap_mutex; + atomic_t mmap_count; +- int mmap_locked; +- struct user_struct *mmap_user; ++ + struct ring_buffer *rb; + struct list_head rb_entry; + +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 839a24f..7ceb270 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -193,9 +193,6 @@ static void cpu_ctx_sched_in(struct perf_cpu_context *cpuctx, + static void update_context_time(struct perf_event_context *ctx); + static u64 perf_event_time(struct perf_event *event); + +-static void ring_buffer_attach(struct perf_event *event, +- struct ring_buffer *rb); +- + void __weak perf_event_print_debug(void) { } + + extern __weak const char *perf_pmu_name(void) +@@ -2849,6 +2846,7 @@ static void free_event_rcu(struct rcu_head *head) + } + + static void ring_buffer_put(struct ring_buffer *rb); ++static void ring_buffer_detach(struct perf_event *event, struct ring_buffer *rb); + + static void free_event(struct perf_event *event) + { +@@ -2873,15 +2871,30 @@ static void free_event(struct perf_event *event) + if (has_branch_stack(event)) { + static_key_slow_dec_deferred(&perf_sched_events); + /* is system-wide event */ +- if (!(event->attach_state & PERF_ATTACH_TASK)) ++ if (!(event->attach_state & PERF_ATTACH_TASK)) { + atomic_dec(&per_cpu(perf_branch_stack_events, + event->cpu)); ++ } + } + } + + if (event->rb) { +- ring_buffer_put(event->rb); +- event->rb = NULL; ++ struct ring_buffer *rb; ++ ++ /* ++ * Can happen when we close an event with re-directed output. ++ * ++ * Since we have a 0 refcount, perf_mmap_close() will skip ++ * over us; possibly making our ring_buffer_put() the last. ++ */ ++ mutex_lock(&event->mmap_mutex); ++ rb = event->rb; ++ if (rb) { ++ rcu_assign_pointer(event->rb, NULL); ++ ring_buffer_detach(event, rb); ++ ring_buffer_put(rb); /* could be last */ ++ } ++ mutex_unlock(&event->mmap_mutex); + } + + if (is_cgroup_event(event)) +@@ -3119,30 +3132,13 @@ static unsigned int perf_poll(struct file *file, poll_table *wait) + unsigned int events = POLL_HUP; + + /* +- * Race between perf_event_set_output() and perf_poll(): perf_poll() +- * grabs the rb reference but perf_event_set_output() overrides it. +- * Here is the timeline for two threads T1, T2: +- * t0: T1, rb = rcu_dereference(event->rb) +- * t1: T2, old_rb = event->rb +- * t2: T2, event->rb = new rb +- * t3: T2, ring_buffer_detach(old_rb) +- * t4: T1, ring_buffer_attach(rb1) +- * t5: T1, poll_wait(event->waitq) +- * +- * To avoid this problem, we grab mmap_mutex in perf_poll() +- * thereby ensuring that the assignment of the new ring buffer +- * and the detachment of the old buffer appear atomic to perf_poll() ++ * Pin the event->rb by taking event->mmap_mutex; otherwise ++ * perf_event_set_output() can swizzle our rb and make us miss wakeups. + */ + mutex_lock(&event->mmap_mutex); +- +- rcu_read_lock(); +- rb = rcu_dereference(event->rb); +- if (rb) { +- ring_buffer_attach(event, rb); ++ rb = event->rb; ++ if (rb) + events = atomic_xchg(&rb->poll, 0); +- } +- rcu_read_unlock(); +- + mutex_unlock(&event->mmap_mutex); + + poll_wait(file, &event->waitq, wait); +@@ -3459,16 +3455,12 @@ static void ring_buffer_attach(struct perf_event *event, + return; + + spin_lock_irqsave(&rb->event_lock, flags); +- if (!list_empty(&event->rb_entry)) +- goto unlock; +- +- list_add(&event->rb_entry, &rb->event_list); +-unlock: ++ if (list_empty(&event->rb_entry)) ++ list_add(&event->rb_entry, &rb->event_list); + spin_unlock_irqrestore(&rb->event_lock, flags); + } + +-static void ring_buffer_detach(struct perf_event *event, +- struct ring_buffer *rb) ++static void ring_buffer_detach(struct perf_event *event, struct ring_buffer *rb) + { + unsigned long flags; + +@@ -3487,13 +3479,10 @@ static void ring_buffer_wakeup(struct perf_event *event) + + rcu_read_lock(); + rb = rcu_dereference(event->rb); +- if (!rb) +- goto unlock; +- +- list_for_each_entry_rcu(event, &rb->event_list, rb_entry) +- wake_up_all(&event->waitq); +- +-unlock: ++ if (rb) { ++ list_for_each_entry_rcu(event, &rb->event_list, rb_entry) ++ wake_up_all(&event->waitq); ++ } + rcu_read_unlock(); + } + +@@ -3522,18 +3511,10 @@ static struct ring_buffer *ring_buffer_get(struct perf_event *event) + + static void ring_buffer_put(struct ring_buffer *rb) + { +- struct perf_event *event, *n; +- unsigned long flags; +- + if (!atomic_dec_and_test(&rb->refcount)) + return; + +- spin_lock_irqsave(&rb->event_lock, flags); +- list_for_each_entry_safe(event, n, &rb->event_list, rb_entry) { +- list_del_init(&event->rb_entry); +- wake_up_all(&event->waitq); +- } +- spin_unlock_irqrestore(&rb->event_lock, flags); ++ WARN_ON_ONCE(!list_empty(&rb->event_list)); + + call_rcu(&rb->rcu_head, rb_free_rcu); + } +@@ -3543,26 +3524,100 @@ static void perf_mmap_open(struct vm_area_struct *vma) + struct perf_event *event = vma->vm_file->private_data; + + atomic_inc(&event->mmap_count); ++ atomic_inc(&event->rb->mmap_count); + } + ++/* ++ * A buffer can be mmap()ed multiple times; either directly through the same ++ * event, or through other events by use of perf_event_set_output(). ++ * ++ * In order to undo the VM accounting done by perf_mmap() we need to destroy ++ * the buffer here, where we still have a VM context. This means we need ++ * to detach all events redirecting to us. ++ */ + static void perf_mmap_close(struct vm_area_struct *vma) + { + struct perf_event *event = vma->vm_file->private_data; + +- if (atomic_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex)) { +- unsigned long size = perf_data_size(event->rb); +- struct user_struct *user = event->mmap_user; +- struct ring_buffer *rb = event->rb; ++ struct ring_buffer *rb = event->rb; ++ struct user_struct *mmap_user = rb->mmap_user; ++ int mmap_locked = rb->mmap_locked; ++ unsigned long size = perf_data_size(rb); ++ ++ atomic_dec(&rb->mmap_count); ++ ++ if (!atomic_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex)) ++ return; ++ ++ /* Detach current event from the buffer. */ ++ rcu_assign_pointer(event->rb, NULL); ++ ring_buffer_detach(event, rb); ++ mutex_unlock(&event->mmap_mutex); ++ ++ /* If there's still other mmap()s of this buffer, we're done. */ ++ if (atomic_read(&rb->mmap_count)) { ++ ring_buffer_put(rb); /* can't be last */ ++ return; ++ } ++ ++ /* ++ * No other mmap()s, detach from all other events that might redirect ++ * into the now unreachable buffer. Somewhat complicated by the ++ * fact that rb::event_lock otherwise nests inside mmap_mutex. ++ */ ++again: ++ rcu_read_lock(); ++ list_for_each_entry_rcu(event, &rb->event_list, rb_entry) { ++ if (!atomic_long_inc_not_zero(&event->refcount)) { ++ /* ++ * This event is en-route to free_event() which will ++ * detach it and remove it from the list. ++ */ ++ continue; ++ } ++ rcu_read_unlock(); + +- atomic_long_sub((size >> PAGE_SHIFT) + 1, &user->locked_vm); +- vma->vm_mm->pinned_vm -= event->mmap_locked; +- rcu_assign_pointer(event->rb, NULL); +- ring_buffer_detach(event, rb); ++ mutex_lock(&event->mmap_mutex); ++ /* ++ * Check we didn't race with perf_event_set_output() which can ++ * swizzle the rb from under us while we were waiting to ++ * acquire mmap_mutex. ++ * ++ * If we find a different rb; ignore this event, a next ++ * iteration will no longer find it on the list. We have to ++ * still restart the iteration to make sure we're not now ++ * iterating the wrong list. ++ */ ++ if (event->rb == rb) { ++ rcu_assign_pointer(event->rb, NULL); ++ ring_buffer_detach(event, rb); ++ ring_buffer_put(rb); /* can't be last, we still have one */ ++ } + mutex_unlock(&event->mmap_mutex); ++ put_event(event); + +- ring_buffer_put(rb); +- free_uid(user); ++ /* ++ * Restart the iteration; either we're on the wrong list or ++ * destroyed its integrity by doing a deletion. ++ */ ++ goto again; + } ++ rcu_read_unlock(); ++ ++ /* ++ * It could be there's still a few 0-ref events on the list; they'll ++ * get cleaned up by free_event() -- they'll also still have their ++ * ref on the rb and will free it whenever they are done with it. ++ * ++ * Aside from that, this buffer is 'fully' detached and unmapped, ++ * undo the VM accounting. ++ */ ++ ++ atomic_long_sub((size >> PAGE_SHIFT) + 1, &mmap_user->locked_vm); ++ vma->vm_mm->pinned_vm -= mmap_locked; ++ free_uid(mmap_user); ++ ++ ring_buffer_put(rb); /* could be last */ + } + + static const struct vm_operations_struct perf_mmap_vmops = { +@@ -3612,12 +3667,24 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma) + return -EINVAL; + + WARN_ON_ONCE(event->ctx->parent_ctx); ++again: + mutex_lock(&event->mmap_mutex); + if (event->rb) { +- if (event->rb->nr_pages == nr_pages) +- atomic_inc(&event->rb->refcount); +- else ++ if (event->rb->nr_pages != nr_pages) { + ret = -EINVAL; ++ goto unlock; ++ } ++ ++ if (!atomic_inc_not_zero(&event->rb->mmap_count)) { ++ /* ++ * Raced against perf_mmap_close() through ++ * perf_event_set_output(). Try again, hope for better ++ * luck. ++ */ ++ mutex_unlock(&event->mmap_mutex); ++ goto again; ++ } ++ + goto unlock; + } + +@@ -3658,12 +3725,16 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma) + ret = -ENOMEM; + goto unlock; + } +- rcu_assign_pointer(event->rb, rb); ++ ++ atomic_set(&rb->mmap_count, 1); ++ rb->mmap_locked = extra; ++ rb->mmap_user = get_current_user(); + + atomic_long_add(user_extra, &user->locked_vm); +- event->mmap_locked = extra; +- event->mmap_user = get_current_user(); +- vma->vm_mm->pinned_vm += event->mmap_locked; ++ vma->vm_mm->pinned_vm += extra; ++ ++ ring_buffer_attach(event, rb); ++ rcu_assign_pointer(event->rb, rb); + + perf_event_update_userpage(event); + +@@ -3672,7 +3743,11 @@ unlock: + atomic_inc(&event->mmap_count); + mutex_unlock(&event->mmap_mutex); + +- vma->vm_flags |= VM_RESERVED; ++ /* ++ * Since pinned accounting is per vm we cannot allow fork() to copy our ++ * vma. ++ */ ++ vma->vm_flags |= VM_DONTCOPY | VM_RESERVED; + vma->vm_ops = &perf_mmap_vmops; + + return ret; +@@ -6161,6 +6236,8 @@ set: + if (atomic_read(&event->mmap_count)) + goto unlock; + ++ old_rb = event->rb; ++ + if (output_event) { + /* get the rb we want to redirect to */ + rb = ring_buffer_get(output_event); +@@ -6168,16 +6245,28 @@ set: + goto unlock; + } + +- old_rb = event->rb; +- rcu_assign_pointer(event->rb, rb); + if (old_rb) + ring_buffer_detach(event, old_rb); ++ ++ if (rb) ++ ring_buffer_attach(event, rb); ++ ++ rcu_assign_pointer(event->rb, rb); ++ ++ if (old_rb) { ++ ring_buffer_put(old_rb); ++ /* ++ * Since we detached before setting the new rb, so that we ++ * could attach the new rb, we could have missed a wakeup. ++ * Provide it now. ++ */ ++ wake_up_all(&event->waitq); ++ } ++ + ret = 0; + unlock: + mutex_unlock(&event->mmap_mutex); + +- if (old_rb) +- ring_buffer_put(old_rb); + out: + return ret; + } +diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c +index bb38c4d..fc8bfcf 100644 +--- a/kernel/events/hw_breakpoint.c ++++ b/kernel/events/hw_breakpoint.c +@@ -147,7 +147,7 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp, + return; + } + +- for_each_online_cpu(cpu) { ++ for_each_possible_cpu(cpu) { + unsigned int nr; + + nr = per_cpu(nr_cpu_bp_pinned[type], cpu); +@@ -233,7 +233,7 @@ toggle_bp_slot(struct perf_event *bp, bool enable, enum bp_type_idx type, + if (cpu >= 0) { + toggle_bp_task_slot(bp, cpu, enable, type, weight); + } else { +- for_each_online_cpu(cpu) ++ for_each_possible_cpu(cpu) + toggle_bp_task_slot(bp, cpu, enable, type, weight); + } + +diff --git a/kernel/events/internal.h b/kernel/events/internal.h +index b0b107f..b400e64 100644 +--- a/kernel/events/internal.h ++++ b/kernel/events/internal.h +@@ -30,6 +30,10 @@ struct ring_buffer { + spinlock_t event_lock; + struct list_head event_list; + ++ atomic_t mmap_count; ++ unsigned long mmap_locked; ++ struct user_struct *mmap_user; ++ + struct perf_event_mmap_page *user_page; + void *data_pages[0]; + }; +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c +index fa07aed..932420d 100644 +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -1880,6 +1880,9 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, + BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d", + conn, code, ident, dlen); + ++ if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE) ++ return NULL; ++ + len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen; + count = min_t(unsigned int, conn->mtu, len); + diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.52-53.patch b/patch/kernel/sun8i-default/0001-patch-3.4.52-53.patch new file mode 100644 index 000000000..b5806cd80 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.52-53.patch @@ -0,0 +1,215 @@ +diff --git a/MAINTAINERS b/MAINTAINERS +index c744d9c..5725829 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -6390,6 +6390,7 @@ STABLE BRANCH + M: Greg Kroah-Hartman + L: stable@vger.kernel.org + S: Supported ++F: Documentation/stable_kernel_rules.txt + + STAGING SUBSYSTEM + M: Greg Kroah-Hartman +diff --git a/Makefile b/Makefile +index 810572b..104049d 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 52 ++SUBLEVEL = 53 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/block/genhd.c b/block/genhd.c +index 60108d9..d815a0f 100644 +--- a/block/genhd.c ++++ b/block/genhd.c +@@ -518,7 +518,7 @@ static void register_disk(struct gendisk *disk) + + ddev->parent = disk->driverfs_dev; + +- dev_set_name(ddev, disk->disk_name); ++ dev_set_name(ddev, "%s", disk->disk_name); + + /* delay uevents, until we scanned partition table */ + dev_set_uevent_suppress(ddev, 1); +diff --git a/crypto/algapi.c b/crypto/algapi.c +index 056571b..b4c046c 100644 +--- a/crypto/algapi.c ++++ b/crypto/algapi.c +@@ -512,7 +512,8 @@ static struct crypto_template *__crypto_lookup_template(const char *name) + + struct crypto_template *crypto_lookup_template(const char *name) + { +- return try_then_request_module(__crypto_lookup_template(name), name); ++ return try_then_request_module(__crypto_lookup_template(name), "%s", ++ name); + } + EXPORT_SYMBOL_GPL(crypto_lookup_template); + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index 3c4c225..386d40e 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -666,7 +666,8 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, + + mutex_unlock(&nbd->tx_lock); + +- thread = kthread_create(nbd_thread, nbd, nbd->disk->disk_name); ++ thread = kthread_create(nbd_thread, nbd, "%s", ++ nbd->disk->disk_name); + if (IS_ERR(thread)) { + mutex_lock(&nbd->tx_lock); + return PTR_ERR(thread); +diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c +index d620b44..8a3aff7 100644 +--- a/drivers/cdrom/cdrom.c ++++ b/drivers/cdrom/cdrom.c +@@ -2882,7 +2882,7 @@ static noinline int mmc_ioctl_cdrom_read_data(struct cdrom_device_info *cdi, + if (lba < 0) + return -EINVAL; + +- cgc->buffer = kmalloc(blocksize, GFP_KERNEL); ++ cgc->buffer = kzalloc(blocksize, GFP_KERNEL); + if (cgc->buffer == NULL) + return -ENOMEM; + +diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c +index 9eca9f1..4c449b2 100644 +--- a/drivers/power/charger-manager.c ++++ b/drivers/power/charger-manager.c +@@ -330,7 +330,7 @@ static void uevent_notify(struct charger_manager *cm, const char *event) + strncpy(env_str, event, UEVENT_BUF_SIZE); + kobject_uevent(&cm->dev->kobj, KOBJ_CHANGE); + +- dev_info(cm->dev, event); ++ dev_info(cm->dev, "%s", event); + } + + /** +diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c +index d4ed9eb..caac1b2 100644 +--- a/drivers/scsi/osd/osd_uld.c ++++ b/drivers/scsi/osd/osd_uld.c +@@ -465,7 +465,7 @@ static int osd_probe(struct device *dev) + oud->class_dev.class = &osd_uld_class; + oud->class_dev.parent = dev; + oud->class_dev.release = __remove; +- error = dev_set_name(&oud->class_dev, disk->disk_name); ++ error = dev_set_name(&oud->class_dev, "%s", disk->disk_name); + if (error) { + OSD_ERR("dev_set_name failed => %d\n", error); + goto err_put_cdev; +diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c +index 2bbb845..3141c1a 100644 +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -140,7 +140,7 @@ sd_store_cache_type(struct device *dev, struct device_attribute *attr, + char *buffer_data; + struct scsi_mode_data data; + struct scsi_sense_hdr sshdr; +- const char *temp = "temporary "; ++ static const char temp[] = "temporary "; + int len; + + if (sdp->type != TYPE_DISK) +diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c +index ffba1ef..40747fe 100644 +--- a/drivers/tty/serial/8250/8250_pci.c ++++ b/drivers/tty/serial/8250/8250_pci.c +@@ -4086,10 +4086,6 @@ static struct pci_device_id serial_pci_tbl[] = { + PCI_VENDOR_ID_IBM, 0x0299, + 0, 0, pbn_b0_bt_2_115200 }, + +- { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, +- 0x1000, 0x0012, +- 0, 0, pbn_b0_bt_2_115200 }, +- + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901, + 0xA000, 0x1000, + 0, 0, pbn_b0_1_115200 }, +diff --git a/fs/hpfs/map.c b/fs/hpfs/map.c +index a790821..ea3d1ca 100644 +--- a/fs/hpfs/map.c ++++ b/fs/hpfs/map.c +@@ -17,7 +17,8 @@ unsigned int *hpfs_map_bitmap(struct super_block *s, unsigned bmp_block, + struct quad_buffer_head *qbh, char *id) + { + secno sec; +- if (hpfs_sb(s)->sb_chk) if (bmp_block * 16384 > hpfs_sb(s)->sb_fs_size) { ++ unsigned n_bands = (hpfs_sb(s)->sb_fs_size + 0x3fff) >> 14; ++ if (hpfs_sb(s)->sb_chk) if (bmp_block >= n_bands) { + hpfs_error(s, "hpfs_map_bitmap called with bad parameter: %08x at %s", bmp_block, id); + return NULL; + } +diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c +index 54f6ecc..0bf578d 100644 +--- a/fs/hpfs/super.c ++++ b/fs/hpfs/super.c +@@ -552,7 +552,13 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) + sbi->sb_cp_table = NULL; + sbi->sb_c_bitmap = -1; + sbi->sb_max_fwd_alloc = 0xffffff; +- ++ ++ if (sbi->sb_fs_size >= 0x80000000) { ++ hpfs_error(s, "invalid size in superblock: %08x", ++ (unsigned)sbi->sb_fs_size); ++ goto bail4; ++ } ++ + /* Load bitmap directory */ + if (!(sbi->sb_bmp_dir = hpfs_load_bitmap_directory(s, le32_to_cpu(superblock->bitmaps)))) + goto bail4; +diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c +index 1798846..cb997b1 100644 +--- a/fs/nfsd/nfs4xdr.c ++++ b/fs/nfsd/nfs4xdr.c +@@ -161,8 +161,8 @@ static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes) + */ + memcpy(p, argp->p, avail); + /* step to next page */ +- argp->p = page_address(argp->pagelist[0]); + argp->pagelist++; ++ argp->p = page_address(argp->pagelist[0]); + if (argp->pagelen < PAGE_SIZE) { + argp->end = argp->p + (argp->pagelen>>2); + argp->pagelen = 0; +diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c +index 6570548..a1e0795 100644 +--- a/kernel/time/tick-sched.c ++++ b/kernel/time/tick-sched.c +@@ -145,7 +145,6 @@ static void tick_nohz_update_jiffies(ktime_t now) + tick_do_update_jiffies64(now); + local_irq_restore(flags); + +- calc_load_exit_idle(); + touch_softlockup_watchdog(); + } + +diff --git a/net/ceph/auth_none.c b/net/ceph/auth_none.c +index 925ca58..8c93fa8 100644 +--- a/net/ceph/auth_none.c ++++ b/net/ceph/auth_none.c +@@ -39,6 +39,11 @@ static int should_authenticate(struct ceph_auth_client *ac) + return xi->starting; + } + ++static int build_request(struct ceph_auth_client *ac, void *buf, void *end) ++{ ++ return 0; ++} ++ + /* + * the generic auth code decode the global_id, and we carry no actual + * authenticate state, so nothing happens here. +@@ -106,6 +111,7 @@ static const struct ceph_auth_client_ops ceph_auth_none_ops = { + .destroy = destroy, + .is_authenticated = is_authenticated, + .should_authenticate = should_authenticate, ++ .build_request = build_request, + .handle_reply = handle_reply, + .create_authorizer = ceph_auth_none_create_authorizer, + .destroy_authorizer = ceph_auth_none_destroy_authorizer, diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.53-54.patch b/patch/kernel/sun8i-default/0001-patch-3.4.53-54.patch new file mode 100644 index 000000000..44dac0755 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.53-54.patch @@ -0,0 +1,534 @@ +diff --git a/Makefile b/Makefile +index 104049d..6ca3657 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 53 ++SUBLEVEL = 54 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c +index 85d6332..a99ed7a 100644 +--- a/arch/arm/kernel/perf_event.c ++++ b/arch/arm/kernel/perf_event.c +@@ -824,6 +824,7 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) + struct frame_tail __user *tail; + + ++ perf_callchain_store(entry, regs->ARM_pc); + tail = (struct frame_tail __user *)regs->ARM_fp - 1; + + while ((entry->nr < PERF_MAX_STACK_DEPTH) && +diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c +index 054cc01..d50a821 100644 +--- a/arch/x86/xen/time.c ++++ b/arch/x86/xen/time.c +@@ -36,9 +36,8 @@ static DEFINE_PER_CPU(struct vcpu_runstate_info, xen_runstate); + /* snapshots of runstate info */ + static DEFINE_PER_CPU(struct vcpu_runstate_info, xen_runstate_snapshot); + +-/* unused ns of stolen and blocked time */ ++/* unused ns of stolen time */ + static DEFINE_PER_CPU(u64, xen_residual_stolen); +-static DEFINE_PER_CPU(u64, xen_residual_blocked); + + /* return an consistent snapshot of 64-bit time/counter value */ + static u64 get64(const u64 *p) +@@ -115,7 +114,7 @@ static void do_stolen_accounting(void) + { + struct vcpu_runstate_info state; + struct vcpu_runstate_info *snap; +- s64 blocked, runnable, offline, stolen; ++ s64 runnable, offline, stolen; + cputime_t ticks; + + get_runstate_snapshot(&state); +@@ -125,7 +124,6 @@ static void do_stolen_accounting(void) + snap = &__get_cpu_var(xen_runstate_snapshot); + + /* work out how much time the VCPU has not been runn*ing* */ +- blocked = state.time[RUNSTATE_blocked] - snap->time[RUNSTATE_blocked]; + runnable = state.time[RUNSTATE_runnable] - snap->time[RUNSTATE_runnable]; + offline = state.time[RUNSTATE_offline] - snap->time[RUNSTATE_offline]; + +@@ -141,17 +139,6 @@ static void do_stolen_accounting(void) + ticks = iter_div_u64_rem(stolen, NS_PER_TICK, &stolen); + __this_cpu_write(xen_residual_stolen, stolen); + account_steal_ticks(ticks); +- +- /* Add the appropriate number of ticks of blocked time, +- including any left-overs from last time. */ +- blocked += __this_cpu_read(xen_residual_blocked); +- +- if (blocked < 0) +- blocked = 0; +- +- ticks = iter_div_u64_rem(blocked, NS_PER_TICK, &blocked); +- __this_cpu_write(xen_residual_blocked, blocked); +- account_idle_ticks(ticks); + } + + /* Get the TSC speed from Xen */ +diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c +index f9914e5..3251d4b 100644 +--- a/drivers/acpi/ec.c ++++ b/drivers/acpi/ec.c +@@ -974,6 +974,10 @@ static struct dmi_system_id __initdata ec_dmi_table[] = { + ec_enlarge_storm_threshold, "CLEVO hardware", { + DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."), + DMI_MATCH(DMI_PRODUCT_NAME, "M720T/M730T"),}, NULL}, ++ { ++ ec_skip_dsdt_scan, "HP Folio 13", { ++ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13"),}, NULL}, + {}, + }; + +diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c +index 71a4d04..aeb8220 100644 +--- a/drivers/ata/ahci.c ++++ b/drivers/ata/ahci.c +@@ -284,6 +284,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { + + /* AMD */ + { PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD Hudson-2 */ ++ { PCI_VDEVICE(AMD, 0x7900), board_ahci }, /* AMD CZ */ + /* AMD is using RAID class only for ahci controllers */ + { PCI_VENDOR_ID_AMD, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_STORAGE_RAID << 8, 0xffffff, board_ahci }, +diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c +index f9eaa82..47a1fb8 100644 +--- a/drivers/ata/libahci.c ++++ b/drivers/ata/libahci.c +@@ -1543,8 +1543,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) + u32 fbs = readl(port_mmio + PORT_FBS); + int pmp = fbs >> PORT_FBS_DWE_OFFSET; + +- if ((fbs & PORT_FBS_SDE) && (pmp < ap->nr_pmp_links) && +- ata_link_online(&ap->pmp_link[pmp])) { ++ if ((fbs & PORT_FBS_SDE) && (pmp < ap->nr_pmp_links)) { + link = &ap->pmp_link[pmp]; + fbs_need_dec = true; + } +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index 758122f..15a6af8 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -2469,10 +2469,10 @@ static void pl330_free_chan_resources(struct dma_chan *chan) + struct dma_pl330_chan *pch = to_pchan(chan); + unsigned long flags; + +- spin_lock_irqsave(&pch->lock, flags); +- + tasklet_kill(&pch->task); + ++ spin_lock_irqsave(&pch->lock, flags); ++ + pl330_release_channel(pch->pl330_chid); + pch->pl330_chid = NULL; + +diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c +index 506b9a0..4763426 100644 +--- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c ++++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c +@@ -104,7 +104,7 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + tx_agc[RF90_PATH_A] = 0x10101010; + tx_agc[RF90_PATH_B] = 0x10101010; + } else if (rtlpriv->dm.dynamic_txhighpower_lvl == +- TXHIGHPWRLEVEL_LEVEL1) { ++ TXHIGHPWRLEVEL_LEVEL2) { + tx_agc[RF90_PATH_A] = 0x00000000; + tx_agc[RF90_PATH_B] = 0x00000000; + } else{ +diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +index 8cf41bb..3f869c9 100644 +--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c ++++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +@@ -357,6 +357,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = { + {RTL_USB_DEVICE(0x2001, 0x330a, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ + {RTL_USB_DEVICE(0x2019, 0xab2b, rtl92cu_hal_cfg)}, /*Planex -Abocom*/ + {RTL_USB_DEVICE(0x20f4, 0x624d, rtl92cu_hal_cfg)}, /*TRENDNet*/ ++ {RTL_USB_DEVICE(0x2357, 0x0100, rtl92cu_hal_cfg)}, /*TP-Link WN8200ND*/ + {RTL_USB_DEVICE(0x7392, 0x7822, rtl92cu_hal_cfg)}, /*Edimax -Edimax*/ + {} + }; +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index 680dbfa..103c95e 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -1062,6 +1062,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk + DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SATA_IDE, quirk_amd_ide_mode); + DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SATA_IDE, quirk_amd_ide_mode); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x7900, quirk_amd_ide_mode); ++DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, 0x7900, quirk_amd_ide_mode); + + /* + * Serverworks CSB5 IDE does not fully support native mode +diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c +index 9694c1e..fc50168 100644 +--- a/drivers/pcmcia/at91_cf.c ++++ b/drivers/pcmcia/at91_cf.c +@@ -100,9 +100,9 @@ static int at91_cf_get_status(struct pcmcia_socket *s, u_int *sp) + int vcc = gpio_is_valid(cf->board->vcc_pin); + + *sp = SS_DETECT | SS_3VCARD; +- if (!rdy || gpio_get_value(rdy)) ++ if (!rdy || gpio_get_value(cf->board->irq_pin)) + *sp |= SS_READY; +- if (!vcc || gpio_get_value(vcc)) ++ if (!vcc || gpio_get_value(cf->board->vcc_pin)) + *sp |= SS_POWERON; + } else + *sp = 0; +diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c +index 0fbe57b..21d63d1 100644 +--- a/drivers/rtc/rtc-rv3029c2.c ++++ b/drivers/rtc/rtc-rv3029c2.c +@@ -310,7 +310,7 @@ static int rv3029c2_rtc_i2c_set_alarm(struct i2c_client *client, + dev_dbg(&client->dev, "alarm IRQ armed\n"); + } else { + /* disable AIE irq */ +- ret = rv3029c2_rtc_i2c_alarm_set_irq(client, 1); ++ ret = rv3029c2_rtc_i2c_alarm_set_irq(client, 0); + if (ret) + return ret; + +diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c +index cb8c162..6de5760 100644 +--- a/drivers/usb/gadget/f_mass_storage.c ++++ b/drivers/usb/gadget/f_mass_storage.c +@@ -511,6 +511,7 @@ static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) + /* Caller must hold fsg->lock */ + static void wakeup_thread(struct fsg_common *common) + { ++ smp_wmb(); /* ensure the write of bh->state is complete */ + /* Tell the main thread that something has happened */ + common->thread_wakeup_needed = 1; + if (common->thread_task) +@@ -730,6 +731,7 @@ static int sleep_thread(struct fsg_common *common) + } + __set_current_state(TASK_RUNNING); + common->thread_wakeup_needed = 0; ++ smp_rmb(); /* ensure the latest bh->state is visible */ + return rc; + } + +diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c +index 5080b1d..3347e9b 100644 +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -369,6 +369,10 @@ static struct xhci_container_ctx *xhci_alloc_container_ctx(struct xhci_hcd *xhci + ctx->size += CTX_SIZE(xhci->hcc_params); + + ctx->bytes = dma_pool_alloc(xhci->device_pool, flags, &ctx->dma); ++ if (!ctx->bytes) { ++ kfree(ctx); ++ return NULL; ++ } + memset(ctx->bytes, 0, ctx->size); + return ctx; + } +diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c +index df90fe5..93ad67e 100644 +--- a/drivers/usb/host/xhci-plat.c ++++ b/drivers/usb/host/xhci-plat.c +@@ -179,5 +179,7 @@ static int xhci_plat_remove(struct platform_device *dev) + + usb_remove_hcd(hcd); ++ iounmap(hcd->regs); ++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); + usb_put_hcd(hcd); + kfree(xhci); + +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 5b24260..33e20e4 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -159,8 +159,6 @@ static void option_instat_callback(struct urb *urb); + #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0x9000 + #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001 + #define NOVATELWIRELESS_PRODUCT_E362 0x9010 +-#define NOVATELWIRELESS_PRODUCT_G1 0xA001 +-#define NOVATELWIRELESS_PRODUCT_G1_M 0xA002 + #define NOVATELWIRELESS_PRODUCT_G2 0xA010 + #define NOVATELWIRELESS_PRODUCT_MC551 0xB001 + +@@ -744,8 +742,6 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC547) }, + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED) }, + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED) }, +- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1) }, +- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1_M) }, + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) }, + /* Novatel Ovation MC551 a.k.a. Verizon USB551L */ + { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) }, +diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c +index d46277d..c7ccbc6 100644 +--- a/drivers/usb/serial/qcserial.c ++++ b/drivers/usb/serial/qcserial.c +@@ -37,7 +37,13 @@ static const struct usb_device_id id_table[] = { + {DEVICE_G1K(0x04da, 0x250c)}, /* Panasonic Gobi QDL device */ + {DEVICE_G1K(0x413c, 0x8172)}, /* Dell Gobi Modem device */ + {DEVICE_G1K(0x413c, 0x8171)}, /* Dell Gobi QDL device */ +- {DEVICE_G1K(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ ++ {DEVICE_G1K(0x1410, 0xa001)}, /* Novatel/Verizon USB-1000 */ ++ {DEVICE_G1K(0x1410, 0xa002)}, /* Novatel Gobi Modem device */ ++ {DEVICE_G1K(0x1410, 0xa003)}, /* Novatel Gobi Modem device */ ++ {DEVICE_G1K(0x1410, 0xa004)}, /* Novatel Gobi Modem device */ ++ {DEVICE_G1K(0x1410, 0xa005)}, /* Novatel Gobi Modem device */ ++ {DEVICE_G1K(0x1410, 0xa006)}, /* Novatel Gobi Modem device */ ++ {DEVICE_G1K(0x1410, 0xa007)}, /* Novatel Gobi Modem device */ + {DEVICE_G1K(0x1410, 0xa008)}, /* Novatel Gobi QDL device */ + {DEVICE_G1K(0x0b05, 0x1776)}, /* Asus Gobi Modem device */ + {DEVICE_G1K(0x0b05, 0x1774)}, /* Asus Gobi QDL device */ +diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h +index a513a54..f2b2ffd 100644 +--- a/fs/cifs/cifs_unicode.h ++++ b/fs/cifs/cifs_unicode.h +@@ -323,14 +323,14 @@ UniToupper(register wchar_t uc) + /* + * UniStrupr: Upper case a unicode string + */ +-static inline wchar_t * +-UniStrupr(register wchar_t *upin) ++static inline __le16 * ++UniStrupr(register __le16 *upin) + { +- register wchar_t *up; ++ register __le16 *up; + + up = upin; + while (*up) { /* For all characters */ +- *up = UniToupper(*up); ++ *up = cpu_to_le16(UniToupper(le16_to_cpu(*up))); + up++; + } + return upin; /* Return input pointer */ +diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c +index 63c460e..6d0c62a 100644 +--- a/fs/cifs/cifsencrypt.c ++++ b/fs/cifs/cifsencrypt.c +@@ -394,7 +394,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, + int rc = 0; + int len; + char nt_hash[CIFS_NTHASH_SIZE]; +- wchar_t *user; ++ __le16 *user; + wchar_t *domain; + wchar_t *server; + +@@ -419,7 +419,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, + return rc; + } + +- /* convert ses->user_name to unicode and uppercase */ ++ /* convert ses->user_name to unicode */ + len = ses->user_name ? strlen(ses->user_name) : 0; + user = kmalloc(2 + (len * 2), GFP_KERNEL); + if (user == NULL) { +@@ -429,7 +429,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, + } + + if (len) { +- len = cifs_strtoUTF16((__le16 *)user, ses->user_name, len, nls_cp); ++ len = cifs_strtoUTF16(user, ses->user_name, len, nls_cp); + UniStrupr(user); + } else { + memset(user, '\0', 2); +diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c +index 6fbfbdb..43944c6 100644 +--- a/fs/cifs/inode.c ++++ b/fs/cifs/inode.c +@@ -549,6 +549,11 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, + fattr->cf_mode &= ~(S_IWUGO); + + fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks); ++ if (fattr->cf_nlink < 1) { ++ cFYI(1, "replacing bogus file nlink value %u\n", ++ fattr->cf_nlink); ++ fattr->cf_nlink = 1; ++ } + } + + fattr->cf_uid = cifs_sb->mnt_uid; +diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c +index d7940b2..fbb9b82 100644 +--- a/fs/ext3/namei.c ++++ b/fs/ext3/namei.c +@@ -573,11 +573,8 @@ static int htree_dirblock_to_tree(struct file *dir_file, + if (!ext3_check_dir_entry("htree_dirblock_to_tree", dir, de, bh, + (block<i_sb)) + +((char *)de - bh->b_data))) { +- /* On error, skip the f_pos to the next block. */ +- dir_file->f_pos = (dir_file->f_pos | +- (dir->i_sb->s_blocksize - 1)) + 1; +- brelse (bh); +- return count; ++ /* silently ignore the rest of the block */ ++ break; + } + ext3fs_dirhash(de->name, de->name_len, hinfo); + if ((hinfo->hash < start_hash) || +diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c +index 0efff1e..b9a3726 100644 +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -4713,7 +4713,7 @@ static int ext4_xattr_fiemap(struct inode *inode, + error = ext4_get_inode_loc(inode, &iloc); + if (error) + return error; +- physical = iloc.bh->b_blocknr << blockbits; ++ physical = (__u64)iloc.bh->b_blocknr << blockbits; + offset = EXT4_GOOD_OLD_INODE_SIZE + + EXT4_I(inode)->i_extra_isize; + physical += offset; +@@ -4721,7 +4721,7 @@ static int ext4_xattr_fiemap(struct inode *inode, + flags |= FIEMAP_EXTENT_DATA_INLINE; + brelse(iloc.bh); + } else { /* external block */ +- physical = EXT4_I(inode)->i_file_acl << blockbits; ++ physical = (__u64)EXT4_I(inode)->i_file_acl << blockbits; + length = inode->i_sb->s_blocksize; + } + +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index 2857e5b..98bff01ee 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -4221,7 +4221,7 @@ int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry, + struct kstat *stat) + { + struct inode *inode; +- unsigned long delalloc_blocks; ++ unsigned long long delalloc_blocks; + + inode = dentry->d_inode; + generic_fillattr(inode, stat); +@@ -4238,7 +4238,7 @@ int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry, + */ + delalloc_blocks = EXT4_I(inode)->i_reserved_data_blocks; + +- stat->blocks += (delalloc_blocks << inode->i_sb->s_blocksize_bits)>>9; ++ stat->blocks += delalloc_blocks << (inode->i_sb->s_blocksize_bits-9); + return 0; + } + +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index 19e4518..8784842 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -4639,11 +4639,16 @@ do_more: + * blocks being freed are metadata. these blocks shouldn't + * be used until this transaction is committed + */ ++ retry: + new_entry = kmem_cache_alloc(ext4_free_data_cachep, GFP_NOFS); + if (!new_entry) { +- ext4_mb_unload_buddy(&e4b); +- err = -ENOMEM; +- goto error_return; ++ /* ++ * We use a retry loop because ++ * ext4_free_blocks() is not allowed to fail. ++ */ ++ cond_resched(); ++ congestion_wait(BLK_RW_ASYNC, HZ/50); ++ goto retry; + } + new_entry->efd_start_cluster = bit; + new_entry->efd_group = block_group; +diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c +index ac76939..9fb3fae 100644 +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -585,11 +585,8 @@ static int htree_dirblock_to_tree(struct file *dir_file, + if (ext4_check_dir_entry(dir, NULL, de, bh, + (block<i_sb)) + + ((char *)de - bh->b_data))) { +- /* On error, skip the f_pos to the next block. */ +- dir_file->f_pos = (dir_file->f_pos | +- (dir->i_sb->s_blocksize - 1)) + 1; +- brelse(bh); +- return count; ++ /* silently ignore the rest of the block */ ++ break; + } + ext4fs_dirhash(de->name, de->name_len, hinfo); + if ((hinfo->hash < start_hash) || +diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c +index 6075ac03..f567127 100644 +--- a/fs/jbd2/transaction.c ++++ b/fs/jbd2/transaction.c +@@ -500,10 +500,10 @@ int jbd2__journal_restart(handle_t *handle, int nblocks, gfp_t gfp_mask) + &transaction->t_outstanding_credits); + if (atomic_dec_and_test(&transaction->t_updates)) + wake_up(&journal->j_wait_updates); ++ tid = transaction->t_tid; + spin_unlock(&transaction->t_handle_lock); + + jbd_debug(2, "restarting handle %p\n", handle); +- tid = transaction->t_tid; + need_to_start = !tid_geq(journal->j_commit_request, tid); + read_unlock(&journal->j_state_lock); + if (need_to_start) +diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c +index 2e3ea30..5b8d944 100644 +--- a/fs/ocfs2/xattr.c ++++ b/fs/ocfs2/xattr.c +@@ -6499,6 +6499,16 @@ static int ocfs2_reflink_xattr_inline(struct ocfs2_xattr_reflink *args) + } + + new_oi = OCFS2_I(args->new_inode); ++ /* ++ * Adjust extent record count to reserve space for extended attribute. ++ * Inline data count had been adjusted in ocfs2_duplicate_inline_data(). ++ */ ++ if (!(new_oi->ip_dyn_features & OCFS2_INLINE_DATA_FL) && ++ !(ocfs2_inode_is_fast_symlink(args->new_inode))) { ++ struct ocfs2_extent_list *el = &new_di->id2.i_list; ++ le16_add_cpu(&el->l_count, -(inline_size / ++ sizeof(struct ocfs2_extent_rec))); ++ } + spin_lock(&new_oi->ip_lock); + new_oi->ip_dyn_features |= OCFS2_HAS_XATTR_FL | OCFS2_INLINE_XATTR_FL; + new_di->i_dyn_features = cpu_to_le16(new_oi->ip_dyn_features); +diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c +index 7684920..86a500d 100644 +--- a/kernel/irq/manage.c ++++ b/kernel/irq/manage.c +@@ -546,9 +546,9 @@ int can_request_irq(unsigned int irq, unsigned long irqflags) + return 0; + + if (irq_settings_can_request(desc)) { +- if (desc->action) +- if (irqflags & desc->action->flags & IRQF_SHARED) +- canrequest =1; ++ if (!desc->action || ++ irqflags & desc->action->flags & IRQF_SHARED) ++ canrequest = 1; + } + irq_put_desc_unlock(desc, flags); + return canrequest; +diff --git a/kernel/timer.c b/kernel/timer.c +index dd93d90..7e0a770 100644 +--- a/kernel/timer.c ++++ b/kernel/timer.c +@@ -145,9 +145,11 @@ static unsigned long round_jiffies_common(unsigned long j, int cpu, + /* now that we have rounded, subtract the extra skew again */ + j -= cpu * 3; + +- if (j <= jiffies) /* rounding ate our timeout entirely; */ +- return original; +- return j; ++ /* ++ * Make sure j is still in the future. Otherwise return the ++ * unmodified value. ++ */ ++ return time_is_after_jiffies(j) ? j : original; + } + + /** diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.54-55.patch b/patch/kernel/sun8i-default/0001-patch-3.4.54-55.patch new file mode 100644 index 000000000..4e4ea14a3 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.54-55.patch @@ -0,0 +1,1697 @@ +diff --git a/Makefile b/Makefile +index 6ca3657..c11116f 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 54 ++SUBLEVEL = 55 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/sparc/kernel/asm-offsets.c b/arch/sparc/kernel/asm-offsets.c +index 68f7e11..ce48203 100644 +--- a/arch/sparc/kernel/asm-offsets.c ++++ b/arch/sparc/kernel/asm-offsets.c +@@ -34,6 +34,8 @@ int foo(void) + DEFINE(AOFF_task_thread, offsetof(struct task_struct, thread)); + BLANK(); + DEFINE(AOFF_mm_context, offsetof(struct mm_struct, context)); ++ BLANK(); ++ DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm)); + + /* DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28); */ + return 0; +diff --git a/arch/sparc/mm/hypersparc.S b/arch/sparc/mm/hypersparc.S +index 44aad32..969f964 100644 +--- a/arch/sparc/mm/hypersparc.S ++++ b/arch/sparc/mm/hypersparc.S +@@ -74,7 +74,7 @@ hypersparc_flush_cache_mm_out: + + /* The things we do for performance... */ + hypersparc_flush_cache_range: +- ld [%o0 + 0x0], %o0 /* XXX vma->vm_mm, GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + #ifndef CONFIG_SMP + ld [%o0 + AOFF_mm_context], %g1 + cmp %g1, -1 +@@ -163,7 +163,7 @@ hypersparc_flush_cache_range_out: + */ + /* Verified, my ass... */ + hypersparc_flush_cache_page: +- ld [%o0 + 0x0], %o0 /* XXX vma->vm_mm, GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + ld [%o0 + AOFF_mm_context], %g2 + #ifndef CONFIG_SMP + cmp %g2, -1 +@@ -284,7 +284,7 @@ hypersparc_flush_tlb_mm_out: + sta %g5, [%g1] ASI_M_MMUREGS + + hypersparc_flush_tlb_range: +- ld [%o0 + 0x00], %o0 /* XXX vma->vm_mm GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + mov SRMMU_CTX_REG, %g1 + ld [%o0 + AOFF_mm_context], %o3 + lda [%g1] ASI_M_MMUREGS, %g5 +@@ -307,7 +307,7 @@ hypersparc_flush_tlb_range_out: + sta %g5, [%g1] ASI_M_MMUREGS + + hypersparc_flush_tlb_page: +- ld [%o0 + 0x00], %o0 /* XXX vma->vm_mm GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + mov SRMMU_CTX_REG, %g1 + ld [%o0 + AOFF_mm_context], %o3 + andn %o1, (PAGE_SIZE - 1), %o1 +diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c +index 0791618..7f8238f 100644 +--- a/arch/sparc/mm/init_64.c ++++ b/arch/sparc/mm/init_64.c +@@ -1067,7 +1067,14 @@ static int __init grab_mblocks(struct mdesc_handle *md) + m->size = *val; + val = mdesc_get_property(md, node, + "address-congruence-offset", NULL); +- m->offset = *val; ++ ++ /* The address-congruence-offset property is optional. ++ * Explicity zero it be identifty this. ++ */ ++ if (val) ++ m->offset = *val; ++ else ++ m->offset = 0UL; + + numadbg("MBLOCK[%d]: base[%llx] size[%llx] offset[%llx]\n", + count - 1, m->base, m->size, m->offset); +diff --git a/arch/sparc/mm/swift.S b/arch/sparc/mm/swift.S +index c801c39..5d2b88d 100644 +--- a/arch/sparc/mm/swift.S ++++ b/arch/sparc/mm/swift.S +@@ -105,7 +105,7 @@ swift_flush_cache_mm_out: + + .globl swift_flush_cache_range + swift_flush_cache_range: +- ld [%o0 + 0x0], %o0 /* XXX vma->vm_mm, GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + sub %o2, %o1, %o2 + sethi %hi(4096), %o3 + cmp %o2, %o3 +@@ -116,7 +116,7 @@ swift_flush_cache_range: + + .globl swift_flush_cache_page + swift_flush_cache_page: +- ld [%o0 + 0x0], %o0 /* XXX vma->vm_mm, GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + 70: + ld [%o0 + AOFF_mm_context], %g2 + cmp %g2, -1 +@@ -219,7 +219,7 @@ swift_flush_sig_insns: + .globl swift_flush_tlb_range + .globl swift_flush_tlb_all + swift_flush_tlb_range: +- ld [%o0 + 0x00], %o0 /* XXX vma->vm_mm GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + swift_flush_tlb_mm: + ld [%o0 + AOFF_mm_context], %g2 + cmp %g2, -1 +@@ -233,7 +233,7 @@ swift_flush_tlb_all_out: + + .globl swift_flush_tlb_page + swift_flush_tlb_page: +- ld [%o0 + 0x00], %o0 /* XXX vma->vm_mm GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + mov SRMMU_CTX_REG, %g1 + ld [%o0 + AOFF_mm_context], %o3 + andn %o1, (PAGE_SIZE - 1), %o1 +diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c +index afd021e..072f553 100644 +--- a/arch/sparc/mm/tlb.c ++++ b/arch/sparc/mm/tlb.c +@@ -115,8 +115,8 @@ no_cache_flush: + } + + if (!tb->active) { +- global_flush_tlb_page(mm, vaddr); + flush_tsb_user_page(mm, vaddr); ++ global_flush_tlb_page(mm, vaddr); + goto out; + } + +diff --git a/arch/sparc/mm/tsunami.S b/arch/sparc/mm/tsunami.S +index 4e55e8f..bf10a34 100644 +--- a/arch/sparc/mm/tsunami.S ++++ b/arch/sparc/mm/tsunami.S +@@ -24,7 +24,7 @@ + /* Sliiick... */ + tsunami_flush_cache_page: + tsunami_flush_cache_range: +- ld [%o0 + 0x0], %o0 /* XXX vma->vm_mm, GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + tsunami_flush_cache_mm: + ld [%o0 + AOFF_mm_context], %g2 + cmp %g2, -1 +@@ -46,7 +46,7 @@ tsunami_flush_sig_insns: + + /* More slick stuff... */ + tsunami_flush_tlb_range: +- ld [%o0 + 0x00], %o0 /* XXX vma->vm_mm GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + tsunami_flush_tlb_mm: + ld [%o0 + AOFF_mm_context], %g2 + cmp %g2, -1 +@@ -65,7 +65,7 @@ tsunami_flush_tlb_out: + + /* This one can be done in a fine grained manner... */ + tsunami_flush_tlb_page: +- ld [%o0 + 0x00], %o0 /* XXX vma->vm_mm GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + mov SRMMU_CTX_REG, %g1 + ld [%o0 + AOFF_mm_context], %o3 + andn %o1, (PAGE_SIZE - 1), %o1 +diff --git a/arch/sparc/mm/viking.S b/arch/sparc/mm/viking.S +index 6dfcc13..a516372 100644 +--- a/arch/sparc/mm/viking.S ++++ b/arch/sparc/mm/viking.S +@@ -109,7 +109,7 @@ viking_mxcc_flush_page: + viking_flush_cache_page: + viking_flush_cache_range: + #ifndef CONFIG_SMP +- ld [%o0 + 0x0], %o0 /* XXX vma->vm_mm, GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + #endif + viking_flush_cache_mm: + #ifndef CONFIG_SMP +@@ -149,7 +149,7 @@ viking_flush_tlb_mm: + #endif + + viking_flush_tlb_range: +- ld [%o0 + 0x00], %o0 /* XXX vma->vm_mm GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + mov SRMMU_CTX_REG, %g1 + ld [%o0 + AOFF_mm_context], %o3 + lda [%g1] ASI_M_MMUREGS, %g5 +@@ -174,7 +174,7 @@ viking_flush_tlb_range: + #endif + + viking_flush_tlb_page: +- ld [%o0 + 0x00], %o0 /* XXX vma->vm_mm GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + mov SRMMU_CTX_REG, %g1 + ld [%o0 + AOFF_mm_context], %o3 + lda [%g1] ASI_M_MMUREGS, %g5 +@@ -240,7 +240,7 @@ sun4dsmp_flush_tlb_range: + tst %g5 + bne 3f + mov SRMMU_CTX_REG, %g1 +- ld [%o0 + 0x00], %o0 /* XXX vma->vm_mm GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + ld [%o0 + AOFF_mm_context], %o3 + lda [%g1] ASI_M_MMUREGS, %g5 + sethi %hi(~((1 << SRMMU_PGDIR_SHIFT) - 1)), %o4 +@@ -266,7 +266,7 @@ sun4dsmp_flush_tlb_page: + tst %g5 + bne 2f + mov SRMMU_CTX_REG, %g1 +- ld [%o0 + 0x00], %o0 /* XXX vma->vm_mm GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + ld [%o0 + AOFF_mm_context], %o3 + lda [%g1] ASI_M_MMUREGS, %g5 + and %o1, PAGE_MASK, %o1 +diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c +index af58f9b..45cc02b 100644 +--- a/drivers/ata/ata_piix.c ++++ b/drivers/ata/ata_piix.c +@@ -352,6 +352,8 @@ static const struct pci_device_id piix_pci_tbl[] = { + /* SATA Controller IDE (BayTrail) */ + { 0x8086, 0x0F20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_byt }, + { 0x8086, 0x0F21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_byt }, ++ /* SATA Controller IDE (Coleto Creek) */ ++ { 0x8086, 0x23a6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, + + { } /* terminate list */ + }; +diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c +index 21b80c5..f63a588 100644 +--- a/drivers/ata/libata-pmp.c ++++ b/drivers/ata/libata-pmp.c +@@ -389,9 +389,13 @@ static void sata_pmp_quirks(struct ata_port *ap) + /* link reports offline after LPM */ + link->flags |= ATA_LFLAG_NO_LPM; + +- /* Class code report is unreliable. */ ++ /* ++ * Class code report is unreliable and SRST times ++ * out under certain configurations. ++ */ + if (link->pmp < 5) +- link->flags |= ATA_LFLAG_ASSUME_ATA; ++ link->flags |= ATA_LFLAG_NO_SRST | ++ ATA_LFLAG_ASSUME_ATA; + + /* port 5 is for SEMB device and it doesn't like SRST */ + if (link->pmp == 5) +@@ -399,20 +403,17 @@ static void sata_pmp_quirks(struct ata_port *ap) + ATA_LFLAG_ASSUME_SEMB; + } + } else if (vendor == 0x1095 && devid == 0x4723) { +- /* sil4723 quirks */ +- ata_for_each_link(link, ap, EDGE) { +- /* link reports offline after LPM */ +- link->flags |= ATA_LFLAG_NO_LPM; +- +- /* class code report is unreliable */ +- if (link->pmp < 2) +- link->flags |= ATA_LFLAG_ASSUME_ATA; +- +- /* the config device at port 2 locks up on SRST */ +- if (link->pmp == 2) +- link->flags |= ATA_LFLAG_NO_SRST | +- ATA_LFLAG_ASSUME_ATA; +- } ++ /* ++ * sil4723 quirks ++ * ++ * Link reports offline after LPM. Class code report is ++ * unreliable. SIMG PMPs never got SRST reliable and the ++ * config device at port 2 locks up on SRST. ++ */ ++ ata_for_each_link(link, ap, EDGE) ++ link->flags |= ATA_LFLAG_NO_LPM | ++ ATA_LFLAG_NO_SRST | ++ ATA_LFLAG_ASSUME_ATA; + } else if (vendor == 0x1095 && devid == 0x4726) { + /* sil4726 quirks */ + ata_for_each_link(link, ap, EDGE) { +diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c +index 99a8444..c0536ed 100644 +--- a/drivers/iommu/amd_iommu.c ++++ b/drivers/iommu/amd_iommu.c +@@ -1309,6 +1309,10 @@ static unsigned long iommu_unmap_page(struct protection_domain *dom, + + /* Large PTE found which maps this address */ + unmap_size = PTE_PAGE_SIZE(*pte); ++ ++ /* Only unmap from the first pte in the page */ ++ if ((unmap_size - 1) & bus_addr) ++ break; + count = PAGE_SIZE_PTE_COUNT(unmap_size); + for (i = 0; i < count; i++) + pte[i] = 0ULL; +@@ -1318,7 +1322,7 @@ static unsigned long iommu_unmap_page(struct protection_domain *dom, + unmapped += unmap_size; + } + +- BUG_ON(!is_power_of_2(unmapped)); ++ BUG_ON(unmapped && !is_power_of_2(unmapped)); + + return unmapped; + } +diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c +index bab0158..b33ad12 100644 +--- a/drivers/net/dummy.c ++++ b/drivers/net/dummy.c +@@ -186,6 +186,8 @@ static int __init dummy_init_module(void) + + rtnl_lock(); + err = __rtnl_link_register(&dummy_link_ops); ++ if (err < 0) ++ goto out; + + for (i = 0; i < numdummies && !err; i++) { + err = dummy_init_one(); +@@ -193,6 +195,8 @@ static int __init dummy_init_module(void) + } + if (err < 0) + __rtnl_link_unregister(&dummy_link_ops); ++ ++out: + rtnl_unlock(); + + return err; +diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +index d53509e..d4a747a 100644 +--- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c ++++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +@@ -1688,8 +1688,8 @@ check_sum: + return 0; + } + +-static void atl1e_tx_map(struct atl1e_adapter *adapter, +- struct sk_buff *skb, struct atl1e_tpd_desc *tpd) ++static int atl1e_tx_map(struct atl1e_adapter *adapter, ++ struct sk_buff *skb, struct atl1e_tpd_desc *tpd) + { + struct atl1e_tpd_desc *use_tpd = NULL; + struct atl1e_tx_buffer *tx_buffer = NULL; +@@ -1700,6 +1700,8 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter, + u16 nr_frags; + u16 f; + int segment; ++ int ring_start = adapter->tx_ring.next_to_use; ++ int ring_end; + + nr_frags = skb_shinfo(skb)->nr_frags; + segment = (tpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK; +@@ -1712,6 +1714,9 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter, + tx_buffer->length = map_len; + tx_buffer->dma = pci_map_single(adapter->pdev, + skb->data, hdr_len, PCI_DMA_TODEVICE); ++ if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma)) ++ return -ENOSPC; ++ + ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE); + mapped_len += map_len; + use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma); +@@ -1738,6 +1743,22 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter, + tx_buffer->dma = + pci_map_single(adapter->pdev, skb->data + mapped_len, + map_len, PCI_DMA_TODEVICE); ++ ++ if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma)) { ++ /* We need to unwind the mappings we've done */ ++ ring_end = adapter->tx_ring.next_to_use; ++ adapter->tx_ring.next_to_use = ring_start; ++ while (adapter->tx_ring.next_to_use != ring_end) { ++ tpd = atl1e_get_tpd(adapter); ++ tx_buffer = atl1e_get_tx_buffer(adapter, tpd); ++ pci_unmap_single(adapter->pdev, tx_buffer->dma, ++ tx_buffer->length, PCI_DMA_TODEVICE); ++ } ++ /* Reset the tx rings next pointer */ ++ adapter->tx_ring.next_to_use = ring_start; ++ return -ENOSPC; ++ } ++ + ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE); + mapped_len += map_len; + use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma); +@@ -1773,6 +1794,23 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter, + (i * MAX_TX_BUF_LEN), + tx_buffer->length, + DMA_TO_DEVICE); ++ ++ if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma)) { ++ /* We need to unwind the mappings we've done */ ++ ring_end = adapter->tx_ring.next_to_use; ++ adapter->tx_ring.next_to_use = ring_start; ++ while (adapter->tx_ring.next_to_use != ring_end) { ++ tpd = atl1e_get_tpd(adapter); ++ tx_buffer = atl1e_get_tx_buffer(adapter, tpd); ++ dma_unmap_page(&adapter->pdev->dev, tx_buffer->dma, ++ tx_buffer->length, DMA_TO_DEVICE); ++ } ++ ++ /* Reset the ring next to use pointer */ ++ adapter->tx_ring.next_to_use = ring_start; ++ return -ENOSPC; ++ } ++ + ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_PAGE); + use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma); + use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) | +@@ -1790,6 +1828,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter, + /* The last buffer info contain the skb address, + so it will be free after unmap */ + tx_buffer->skb = skb; ++ return 0; + } + + static void atl1e_tx_queue(struct atl1e_adapter *adapter, u16 count, +@@ -1857,10 +1896,15 @@ static netdev_tx_t atl1e_xmit_frame(struct sk_buff *skb, + return NETDEV_TX_OK; + } + +- atl1e_tx_map(adapter, skb, tpd); ++ if (atl1e_tx_map(adapter, skb, tpd)) { ++ dev_kfree_skb_any(skb); ++ goto out; ++ } ++ + atl1e_tx_queue(adapter, tpd_req, tpd); + + netdev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */ ++out: + spin_unlock_irqrestore(&adapter->tx_lock, flags); + return NETDEV_TX_OK; + } +diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c +index d63e09b..16caeba 100644 +--- a/drivers/net/ethernet/renesas/sh_eth.c ++++ b/drivers/net/ethernet/renesas/sh_eth.c +@@ -137,8 +137,9 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { + .rmcr_value = 0x00000001, + + .tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO, +- .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE | +- EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI, ++ .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | ++ EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | ++ EESR_ECI, + .tx_error_check = EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE, + + .apr = 1, +@@ -252,9 +253,9 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data_giga = { + .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, + + .tx_check = EESR_TC1 | EESR_FTC, +- .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \ +- EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \ +- EESR_ECI, ++ .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | ++ EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE | ++ EESR_TDE | EESR_ECI, + .tx_error_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \ + EESR_TFE, + .fdr_value = 0x0000072f, +@@ -361,9 +362,9 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { + .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, + + .tx_check = EESR_TC1 | EESR_FTC, +- .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \ +- EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \ +- EESR_ECI, ++ .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | ++ EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE | ++ EESR_TDE | EESR_ECI, + .tx_error_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \ + EESR_TFE, + +diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h +index 0fa14afc..c49097f 100644 +--- a/drivers/net/ethernet/renesas/sh_eth.h ++++ b/drivers/net/ethernet/renesas/sh_eth.h +@@ -467,7 +467,7 @@ enum EESR_BIT { + + #define DEFAULT_TX_CHECK (EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | \ + EESR_RTO) +-#define DEFAULT_EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | \ ++#define DEFAULT_EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | \ + EESR_RDE | EESR_RFRMER | EESR_ADE | \ + EESR_TFE | EESR_TDE | EESR_ECI) + #define DEFAULT_TX_ERROR_CHECK (EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | \ +diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c +index 38e3ae9..8e2ac64 100644 +--- a/drivers/net/ethernet/sun/sunvnet.c ++++ b/drivers/net/ethernet/sun/sunvnet.c +@@ -1243,6 +1243,8 @@ static int vnet_port_remove(struct vio_dev *vdev) + dev_set_drvdata(&vdev->dev, NULL); + + kfree(port); ++ ++ unregister_netdev(vp->dev); + } + return 0; + } +diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c +index 344dceb..635d01c 100644 +--- a/drivers/net/ifb.c ++++ b/drivers/net/ifb.c +@@ -290,11 +290,17 @@ static int __init ifb_init_module(void) + + rtnl_lock(); + err = __rtnl_link_register(&ifb_link_ops); ++ if (err < 0) ++ goto out; + +- for (i = 0; i < numifbs && !err; i++) ++ for (i = 0; i < numifbs && !err; i++) { + err = ifb_init_one(i); ++ cond_resched(); ++ } + if (err) + __rtnl_link_unregister(&ifb_link_ops); ++ ++out: + rtnl_unlock(); + + return err; +diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c +index b99c418..5151f06 100644 +--- a/drivers/net/macvtap.c ++++ b/drivers/net/macvtap.c +@@ -534,8 +534,10 @@ static int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from, + return -EMSGSIZE; + num_pages = get_user_pages_fast(base, size, 0, &page[i]); + if (num_pages != size) { +- for (i = 0; i < num_pages; i++) +- put_page(page[i]); ++ int j; ++ ++ for (j = 0; j < num_pages; j++) ++ put_page(page[i + j]); + } + truesize = size * PAGE_SIZE; + skb->data_len += len; +@@ -654,6 +656,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, + int vnet_hdr_len = 0; + int copylen = 0; + bool zerocopy = false; ++ size_t linear; + + if (q->flags & IFF_VNET_HDR) { + vnet_hdr_len = q->vnet_hdr_sz; +@@ -708,11 +711,14 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, + copylen = vnet_hdr.hdr_len; + if (!copylen) + copylen = GOODCOPY_LEN; +- } else ++ linear = copylen; ++ } else { + copylen = len; ++ linear = vnet_hdr.hdr_len; ++ } + + skb = macvtap_alloc_skb(&q->sk, NET_IP_ALIGN, copylen, +- vnet_hdr.hdr_len, noblock, &err); ++ linear, noblock, &err); + if (!skb) + goto err; + +diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c +index bbd249d..85e7453 100644 +--- a/drivers/net/wireless/ath/ath9k/calib.c ++++ b/drivers/net/wireless/ath/ath9k/calib.c +@@ -389,7 +389,6 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan) + + if (!caldata) { + chan->noisefloor = nf; +- ah->noise = ath9k_hw_getchan_noise(ah, chan); + return false; + } + +diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c +index 2ce6bf5..72cb121 100644 +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c +@@ -4627,8 +4627,8 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) + default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); + + for (i = 14; i < spec->num_channels; i++) { +- info[i].default_power1 = default_power1[i]; +- info[i].default_power2 = default_power2[i]; ++ info[i].default_power1 = default_power1[i - 14]; ++ info[i].default_power2 = default_power2[i - 14]; + } + } + +diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c +index bdaba3f..0cb0eec 100644 +--- a/drivers/net/wireless/rt2x00/rt61pci.c ++++ b/drivers/net/wireless/rt2x00/rt61pci.c +@@ -2822,7 +2822,8 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) + tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); + for (i = 14; i < spec->num_channels; i++) { + info[i].max_power = MAX_TXPOWER; +- info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); ++ info[i].default_power1 = ++ TXPOWER_FROM_DEV(tx_power[i - 14]); + } + } + +diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c +index fda8671..ffdd32e 100644 +--- a/drivers/net/wireless/rt2x00/rt73usb.c ++++ b/drivers/net/wireless/rt2x00/rt73usb.c +@@ -2167,7 +2167,8 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) + tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); + for (i = 14; i < spec->num_channels; i++) { + info[i].max_power = MAX_TXPOWER; +- info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); ++ info[i].default_power1 = ++ TXPOWER_FROM_DEV(tx_power[i - 14]); + } + } + +diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c +index 2136fc2..5fdf70b 100644 +--- a/drivers/s390/scsi/zfcp_fsf.c ++++ b/drivers/s390/scsi/zfcp_fsf.c +@@ -563,6 +563,10 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req) + fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN; + adapter->hydra_version = 0; + ++ /* avoids adapter shutdown to be able to recognize ++ * events such as LINK UP */ ++ atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, ++ &adapter->status); + zfcp_fsf_link_down_info_eval(req, + &qtcb->header.fsf_status_qual.link_down_info); + break; +diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c +index b79576b..7b35364 100644 +--- a/drivers/s390/scsi/zfcp_scsi.c ++++ b/drivers/s390/scsi/zfcp_scsi.c +@@ -3,7 +3,7 @@ + * + * Interface to Linux SCSI midlayer. + * +- * Copyright IBM Corporation 2002, 2010 ++ * Copyright IBM Corp. 2002, 2013 + */ + + #define KMSG_COMPONENT "zfcp" +@@ -311,8 +311,12 @@ static struct scsi_host_template zfcp_scsi_host_template = { + .proc_name = "zfcp", + .can_queue = 4096, + .this_id = -1, +- .sg_tablesize = 1, /* adjusted later */ +- .max_sectors = 8, /* adjusted later */ ++ .sg_tablesize = (((QDIO_MAX_ELEMENTS_PER_BUFFER - 1) ++ * ZFCP_QDIO_MAX_SBALS_PER_REQ) - 2), ++ /* GCD, adjusted later */ ++ .max_sectors = (((QDIO_MAX_ELEMENTS_PER_BUFFER - 1) ++ * ZFCP_QDIO_MAX_SBALS_PER_REQ) - 2) * 8, ++ /* GCD, adjusted later */ + .dma_boundary = ZFCP_QDIO_SBALE_LEN - 1, + .cmd_per_lun = 1, + .use_clustering = 1, +diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c +index e897ce9..f8a2d12 100644 +--- a/drivers/scsi/bnx2fc/bnx2fc_io.c ++++ b/drivers/scsi/bnx2fc/bnx2fc_io.c +@@ -1786,7 +1786,7 @@ static void bnx2fc_parse_fcp_rsp(struct bnx2fc_cmd *io_req, + fcp_sns_len = SCSI_SENSE_BUFFERSIZE; + } + +- memset(sc_cmd->sense_buffer, 0, sizeof(sc_cmd->sense_buffer)); ++ memset(sc_cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); + if (fcp_sns_len) + memcpy(sc_cmd->sense_buffer, rq_data, fcp_sns_len); + +diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c +index 6308a8d..073d5ad 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_base.c ++++ b/drivers/scsi/megaraid/megaraid_sas_base.c +@@ -4817,10 +4817,12 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, + sense, sense_handle); + } + +- for (i = 0; i < ioc->sge_count && kbuff_arr[i]; i++) { +- dma_free_coherent(&instance->pdev->dev, +- kern_sge32[i].length, +- kbuff_arr[i], kern_sge32[i].phys_addr); ++ for (i = 0; i < ioc->sge_count; i++) { ++ if (kbuff_arr[i]) ++ dma_free_coherent(&instance->pdev->dev, ++ kern_sge32[i].length, ++ kbuff_arr[i], ++ kern_sge32[i].phys_addr); + } + + megasas_return_cmd(instance, cmd); +diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c +index d953a57..35a05d1 100644 +--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c ++++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c +@@ -3963,11 +3963,7 @@ _scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *)) + else + mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; + } else +-/* MPI Revision I (UNIT = 0xA) - removed MPI2_SCSIIO_CONTROL_UNTAGGED */ +-/* mpi_control |= MPI2_SCSIIO_CONTROL_UNTAGGED; +- */ +- mpi_control |= (0x500); +- ++ mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; + } else + mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; + /* Make sure Device is not raid volume. +diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c +index d9811e4..b53065b 100644 +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -60,6 +60,7 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */ + { USB_DEVICE(0x0489, 0xE003) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */ + { USB_DEVICE(0x0745, 0x1000) }, /* CipherLab USB CCD Barcode Scanner 1000 */ ++ { USB_DEVICE(0x0846, 0x1100) }, /* NetGear Managed Switch M4100 series, M5300 series, M7100 series */ + { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ + { USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */ + { USB_DEVICE(0x0BED, 0x1100) }, /* MEI (TM) Cashflow-SC Bill/Voucher Acceptor */ +@@ -124,6 +125,8 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */ + { USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */ + { USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */ ++ { USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */ ++ { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */ + { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ + { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ + { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */ +@@ -154,6 +157,7 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */ + { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ + { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ ++ { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */ + { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */ + { USB_DEVICE(0x1E29, 0x0102) }, /* Festo CPX-USB */ + { USB_DEVICE(0x1E29, 0x0501) }, /* Festo CMSP */ +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 33e20e4..a37f14c 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -347,17 +347,12 @@ static void option_instat_callback(struct urb *urb); + #define OLIVETTI_VENDOR_ID 0x0b3c + #define OLIVETTI_PRODUCT_OLICARD100 0xc000 + #define OLIVETTI_PRODUCT_OLICARD145 0xc003 ++#define OLIVETTI_PRODUCT_OLICARD200 0xc005 + + /* Celot products */ + #define CELOT_VENDOR_ID 0x211f + #define CELOT_PRODUCT_CT680M 0x6801 + +-/* ONDA Communication vendor id */ +-#define ONDA_VENDOR_ID 0x1ee8 +- +-/* ONDA MT825UP HSDPA 14.2 modem */ +-#define ONDA_MT825UP 0x000b +- + /* Samsung products */ + #define SAMSUNG_VENDOR_ID 0x04e8 + #define SAMSUNG_PRODUCT_GT_B3730 0x6889 +@@ -450,7 +445,8 @@ static void option_instat_callback(struct urb *urb); + + /* Hyundai Petatel Inc. products */ + #define PETATEL_VENDOR_ID 0x1ff4 +-#define PETATEL_PRODUCT_NP10T 0x600e ++#define PETATEL_PRODUCT_NP10T_600A 0x600a ++#define PETATEL_PRODUCT_NP10T_600E 0x600e + + /* TP-LINK Incorporated products */ + #define TPLINK_VENDOR_ID 0x2357 +@@ -797,6 +793,7 @@ 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(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 */ + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */ + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) }, +@@ -832,7 +829,8 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0017, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0018, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0019, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0019, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + { 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 }, +@@ -1278,8 +1276,8 @@ static const struct usb_device_id option_ids[] = { + + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD145) }, ++ { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD200) }, + { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ +- { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP 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) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM610) }, +@@ -1351,9 +1349,12 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM2, 0xff, 0x02, 0x01) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM2, 0xff, 0x00, 0x00) }, + { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) }, +- { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T) }, ++ { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600A) }, ++ { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600E) }, + { USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ { USB_DEVICE(TPLINK_VENDOR_ID, 0x9000), /* TP-Link MA260 */ ++ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { 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) */ +@@ -1361,6 +1362,8 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x00, 0x00) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x02, 0x01) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) }, ++ { 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 */ + { } /* Terminating entry */ + }; + MODULE_DEVICE_TABLE(usb, option_ids); +diff --git a/fs/block_dev.c b/fs/block_dev.c +index 2f3879c..319d9c7 100644 +--- a/fs/block_dev.c ++++ b/fs/block_dev.c +@@ -57,17 +57,24 @@ static void bdev_inode_switch_bdi(struct inode *inode, + struct backing_dev_info *dst) + { + struct backing_dev_info *old = inode->i_data.backing_dev_info; ++ bool wakeup_bdi = false; + + if (unlikely(dst == old)) /* deadlock avoidance */ + return; + bdi_lock_two(&old->wb, &dst->wb); + spin_lock(&inode->i_lock); + inode->i_data.backing_dev_info = dst; +- if (inode->i_state & I_DIRTY) ++ if (inode->i_state & I_DIRTY) { ++ if (bdi_cap_writeback_dirty(dst) && !wb_has_dirty_io(&dst->wb)) ++ wakeup_bdi = true; + list_move(&inode->i_wb_list, &dst->wb.b_dirty); ++ } + spin_unlock(&inode->i_lock); + spin_unlock(&old->wb.list_lock); + spin_unlock(&dst->wb.list_lock); ++ ++ if (wakeup_bdi) ++ bdi_wakeup_thread_delayed(dst); + } + + sector_t blkdev_max_block(struct block_device *bdev) +diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c +index 0752817..aad0f39 100644 +--- a/fs/ext3/inode.c ++++ b/fs/ext3/inode.c +@@ -218,7 +218,8 @@ void ext3_evict_inode (struct inode *inode) + */ + if (inode->i_nlink && ext3_should_journal_data(inode) && + EXT3_SB(inode->i_sb)->s_journal && +- (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode))) { ++ (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode)) && ++ inode->i_ino != EXT3_JOURNAL_INO) { + tid_t commit_tid = atomic_read(&ei->i_datasync_tid); + journal_t *journal = EXT3_SB(inode->i_sb)->s_journal; + +diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c +index e46353f..aff1c61 100644 +--- a/fs/lockd/svclock.c ++++ b/fs/lockd/svclock.c +@@ -941,6 +941,7 @@ nlmsvc_retry_blocked(void) + unsigned long timeout = MAX_SCHEDULE_TIMEOUT; + struct nlm_block *block; + ++ spin_lock(&nlm_blocked_lock); + while (!list_empty(&nlm_blocked) && !kthread_should_stop()) { + block = list_entry(nlm_blocked.next, struct nlm_block, b_list); + +@@ -950,6 +951,7 @@ nlmsvc_retry_blocked(void) + timeout = block->b_when - jiffies; + break; + } ++ spin_unlock(&nlm_blocked_lock); + + dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n", + block, block->b_when); +@@ -959,7 +961,9 @@ nlmsvc_retry_blocked(void) + retry_deferred_block(block); + } else + nlmsvc_grant_blocked(block); ++ spin_lock(&nlm_blocked_lock); + } ++ spin_unlock(&nlm_blocked_lock); + + return timeout; + } +diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h +index b5f927f..732c962 100644 +--- a/include/linux/if_pppox.h ++++ b/include/linux/if_pppox.h +@@ -128,11 +128,11 @@ struct pppoe_tag { + + struct pppoe_hdr { + #if defined(__LITTLE_ENDIAN_BITFIELD) +- __u8 ver : 4; + __u8 type : 4; ++ __u8 ver : 4; + #elif defined(__BIG_ENDIAN_BITFIELD) +- __u8 type : 4; + __u8 ver : 4; ++ __u8 type : 4; + #else + #error "Please fix " + #endif +diff --git a/include/net/addrconf.h b/include/net/addrconf.h +index 757a176..1a77dbb 100644 +--- a/include/net/addrconf.h ++++ b/include/net/addrconf.h +@@ -81,6 +81,9 @@ extern int ipv6_dev_get_saddr(struct net *net, + const struct in6_addr *daddr, + unsigned int srcprefs, + struct in6_addr *saddr); ++extern int __ipv6_get_lladdr(struct inet6_dev *idev, ++ struct in6_addr *addr, ++ unsigned char banned_flags); + extern int ipv6_get_lladdr(struct net_device *dev, + struct in6_addr *addr, + unsigned char banned_flags); +diff --git a/include/net/udp.h b/include/net/udp.h +index 5d606d9..d0bf5b6 100644 +--- a/include/net/udp.h ++++ b/include/net/udp.h +@@ -181,6 +181,7 @@ extern int udp_get_port(struct sock *sk, unsigned short snum, + extern void udp_err(struct sk_buff *, u32); + extern int udp_sendmsg(struct kiocb *iocb, struct sock *sk, + struct msghdr *msg, size_t len); ++extern int udp_push_pending_frames(struct sock *sk); + extern void udp_flush_pending_frames(struct sock *sk); + extern int udp_rcv(struct sk_buff *skb); + extern int udp_ioctl(struct sock *sk, int cmd, unsigned long arg); +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 7ceb270..d074cf0 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -719,8 +719,18 @@ perf_lock_task_context(struct task_struct *task, int ctxn, unsigned long *flags) + { + struct perf_event_context *ctx; + +- rcu_read_lock(); + retry: ++ /* ++ * One of the few rules of preemptible RCU is that one cannot do ++ * rcu_read_unlock() while holding a scheduler (or nested) lock when ++ * part of the read side critical section was preemptible -- see ++ * rcu_read_unlock_special(). ++ * ++ * Since ctx->lock nests under rq->lock we must ensure the entire read ++ * side critical section is non-preemptible. ++ */ ++ preempt_disable(); ++ rcu_read_lock(); + ctx = rcu_dereference(task->perf_event_ctxp[ctxn]); + if (ctx) { + /* +@@ -736,6 +746,8 @@ retry: + raw_spin_lock_irqsave(&ctx->lock, *flags); + if (ctx != rcu_dereference(task->perf_event_ctxp[ctxn])) { + raw_spin_unlock_irqrestore(&ctx->lock, *flags); ++ rcu_read_unlock(); ++ preempt_enable(); + goto retry; + } + +@@ -745,6 +757,7 @@ retry: + } + } + rcu_read_unlock(); ++ preempt_enable(); + return ctx; + } + +@@ -1702,7 +1715,16 @@ static int __perf_event_enable(void *info) + struct perf_cpu_context *cpuctx = __get_cpu_context(ctx); + int err; + +- if (WARN_ON_ONCE(!ctx->is_active)) ++ /* ++ * There's a time window between 'ctx->is_active' check ++ * in perf_event_enable function and this place having: ++ * - IRQs on ++ * - ctx->lock unlocked ++ * ++ * where the task could be killed and 'ctx' deactivated ++ * by perf_event_exit_task. ++ */ ++ if (!ctx->is_active) + return -EINVAL; + + raw_spin_lock(&ctx->lock); +@@ -6933,7 +6955,7 @@ inherit_task_group(struct perf_event *event, struct task_struct *parent, + * child. + */ + +- child_ctx = alloc_perf_context(event->pmu, child); ++ child_ctx = alloc_perf_context(parent_ctx->pmu, child); + if (!child_ctx) + return -ENOMEM; + +diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c +index 60f7e32..a57ef25 100644 +--- a/kernel/hrtimer.c ++++ b/kernel/hrtimer.c +@@ -707,17 +707,20 @@ static int hrtimer_switch_to_hres(void) + return 1; + } + ++static void clock_was_set_work(struct work_struct *work) ++{ ++ clock_was_set(); ++} ++ ++static DECLARE_WORK(hrtimer_work, clock_was_set_work); ++ + /* +- * Called from timekeeping code to reprogramm the hrtimer interrupt +- * device. If called from the timer interrupt context we defer it to +- * softirq context. ++ * Called from timekeeping and resume code to reprogramm the hrtimer ++ * interrupt device on all cpus. + */ + void clock_was_set_delayed(void) + { +- struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases); +- +- cpu_base->clock_was_set = 1; +- __raise_softirq_irqoff(HRTIMER_SOFTIRQ); ++ schedule_work(&hrtimer_work); + } + + #else +@@ -766,8 +769,10 @@ void hrtimers_resume(void) + WARN_ONCE(!irqs_disabled(), + KERN_INFO "hrtimers_resume() called with IRQs enabled!"); + ++ /* Retrigger on the local CPU */ + retrigger_next_event(NULL); +- timerfd_clock_was_set(); ++ /* And schedule a retrigger for all others */ ++ clock_was_set_delayed(); + } + + static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer) +@@ -1416,13 +1421,6 @@ void hrtimer_peek_ahead_timers(void) + + static void run_hrtimer_softirq(struct softirq_action *h) + { +- struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases); +- +- if (cpu_base->clock_was_set) { +- cpu_base->clock_was_set = 0; +- clock_was_set(); +- } +- + hrtimer_peek_ahead_timers(); + } + +diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c +index 239a323..f8961bf 100644 +--- a/kernel/time/tick-broadcast.c ++++ b/kernel/time/tick-broadcast.c +@@ -400,7 +400,15 @@ void tick_check_oneshot_broadcast(int cpu) + if (cpumask_test_cpu(cpu, to_cpumask(tick_broadcast_oneshot_mask))) { + struct tick_device *td = &per_cpu(tick_cpu_device, cpu); + +- clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_ONESHOT); ++ /* ++ * We might be in the middle of switching over from ++ * periodic to oneshot. If the CPU has not yet ++ * switched over, leave the device alone. ++ */ ++ if (td->mode == TICKDEV_MODE_ONESHOT) { ++ clockevents_set_mode(td->evtdev, ++ CLOCK_EVT_MODE_ONESHOT); ++ } + } + } + +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index 75c11bf..13cd224 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -687,7 +687,15 @@ __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) + + memcpy(max_data->comm, tsk->comm, TASK_COMM_LEN); + max_data->pid = tsk->pid; +- max_data->uid = task_uid(tsk); ++ /* ++ * If tsk == current, then use current_uid(), as that does not use ++ * RCU. The irq tracer can be called out of RCU scope. ++ */ ++ if (tsk == current) ++ max_data->uid = current_uid(); ++ else ++ max_data->uid = task_uid(tsk); ++ + max_data->nice = tsk->static_prio - 20 - MAX_RT_PRIO; + max_data->policy = tsk->policy; + max_data->rt_priority = tsk->rt_priority; +diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c +index 96fc733..e675182 100644 +--- a/kernel/trace/trace_syscalls.c ++++ b/kernel/trace/trace_syscalls.c +@@ -305,6 +305,8 @@ void ftrace_syscall_enter(void *ignore, struct pt_regs *regs, long id) + struct ring_buffer *buffer; + int size; + int syscall_nr; ++ unsigned long irq_flags; ++ int pc; + + syscall_nr = syscall_get_nr(current, regs); + if (syscall_nr < 0) +@@ -318,8 +320,11 @@ void ftrace_syscall_enter(void *ignore, struct pt_regs *regs, long id) + + size = sizeof(*entry) + sizeof(unsigned long) * sys_data->nb_args; + ++ local_save_flags(irq_flags); ++ pc = preempt_count(); ++ + event = trace_current_buffer_lock_reserve(&buffer, +- sys_data->enter_event->event.type, size, 0, 0); ++ sys_data->enter_event->event.type, size, irq_flags, pc); + if (!event) + return; + +@@ -329,7 +334,8 @@ void ftrace_syscall_enter(void *ignore, struct pt_regs *regs, long id) + + if (!filter_current_check_discard(buffer, sys_data->enter_event, + entry, event)) +- trace_current_buffer_unlock_commit(buffer, event, 0, 0); ++ trace_current_buffer_unlock_commit(buffer, event, ++ irq_flags, pc); + } + + void ftrace_syscall_exit(void *ignore, struct pt_regs *regs, long ret) +@@ -339,6 +345,8 @@ void ftrace_syscall_exit(void *ignore, struct pt_regs *regs, long ret) + struct ring_buffer_event *event; + struct ring_buffer *buffer; + int syscall_nr; ++ unsigned long irq_flags; ++ int pc; + + syscall_nr = syscall_get_nr(current, regs); + if (syscall_nr < 0) +@@ -351,7 +359,8 @@ void ftrace_syscall_exit(void *ignore, struct pt_regs *regs, long ret) + return; + + event = trace_current_buffer_lock_reserve(&buffer, +- sys_data->exit_event->event.type, sizeof(*entry), 0, 0); ++ sys_data->exit_event->event.type, sizeof(*entry), ++ irq_flags, pc); + if (!event) + return; + +@@ -361,7 +370,8 @@ void ftrace_syscall_exit(void *ignore, struct pt_regs *regs, long ret) + + if (!filter_current_check_discard(buffer, sys_data->exit_event, + entry, event)) +- trace_current_buffer_unlock_commit(buffer, event, 0, 0); ++ trace_current_buffer_unlock_commit(buffer, event, ++ irq_flags, pc); + } + + int reg_event_syscall_enter(struct ftrace_event_call *call) +diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c +index daeb19d..8f45392 100644 +--- a/net/8021q/vlan_dev.c ++++ b/net/8021q/vlan_dev.c +@@ -73,6 +73,8 @@ vlan_dev_get_egress_qos_mask(struct net_device *dev, struct sk_buff *skb) + { + struct vlan_priority_tci_mapping *mp; + ++ smp_rmb(); /* coupled with smp_wmb() in vlan_dev_set_egress_priority() */ ++ + mp = vlan_dev_priv(dev)->egress_priority_map[(skb->priority & 0xF)]; + while (mp) { + if (mp->priority == skb->priority) { +@@ -235,6 +237,11 @@ int vlan_dev_set_egress_priority(const struct net_device *dev, + np->next = mp; + np->priority = skb_prio; + np->vlan_qos = vlan_qos; ++ /* Before inserting this element in hash table, make sure all its fields ++ * are committed to memory. ++ * coupled with smp_rmb() in vlan_dev_get_egress_qos_mask() ++ */ ++ smp_wmb(); + vlan->egress_priority_map[skb_prio & 0xF] = np; + if (vlan_qos) + vlan->nr_egress_mappings++; +diff --git a/net/9p/trans_common.c b/net/9p/trans_common.c +index de8df95..2ee3879 100644 +--- a/net/9p/trans_common.c ++++ b/net/9p/trans_common.c +@@ -24,11 +24,11 @@ + */ + void p9_release_pages(struct page **pages, int nr_pages) + { +- int i = 0; +- while (pages[i] && nr_pages--) { +- put_page(pages[i]); +- i++; +- } ++ int i; ++ ++ for (i = 0; i < nr_pages; i++) ++ if (pages[i]) ++ put_page(pages[i]); + } + EXPORT_SYMBOL(p9_release_pages); + +diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c +index 27ca25e..9069071 100644 +--- a/net/bridge/br_multicast.c ++++ b/net/bridge/br_multicast.c +@@ -467,8 +467,9 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br, + skb_set_transport_header(skb, skb->len); + mldq = (struct mld_msg *) icmp6_hdr(skb); + +- interval = ipv6_addr_any(group) ? br->multicast_last_member_interval : +- br->multicast_query_response_interval; ++ interval = ipv6_addr_any(group) ? ++ br->multicast_query_response_interval : ++ br->multicast_last_member_interval; + + mldq->mld_type = ICMPV6_MGM_QUERY; + mldq->mld_code = 0; +diff --git a/net/core/neighbour.c b/net/core/neighbour.c +index ac88107..69b7ca3 100644 +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -237,7 +237,7 @@ static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev) + we must kill timers etc. and move + it to safe state. + */ +- skb_queue_purge(&n->arp_queue); ++ __skb_queue_purge(&n->arp_queue); + n->arp_queue_len_bytes = 0; + n->output = neigh_blackhole; + if (n->nud_state & NUD_VALID) +@@ -300,7 +300,7 @@ static struct neighbour *neigh_alloc(struct neigh_table *tbl, struct net_device + if (!n) + goto out_entries; + +- skb_queue_head_init(&n->arp_queue); ++ __skb_queue_head_init(&n->arp_queue); + rwlock_init(&n->lock); + seqlock_init(&n->ha_lock); + n->updated = n->used = now; +@@ -721,7 +721,9 @@ void neigh_destroy(struct neighbour *neigh) + if (neigh_del_timer(neigh)) + printk(KERN_WARNING "Impossible event.\n"); + +- skb_queue_purge(&neigh->arp_queue); ++ write_lock_bh(&neigh->lock); ++ __skb_queue_purge(&neigh->arp_queue); ++ write_unlock_bh(&neigh->lock); + neigh->arp_queue_len_bytes = 0; + + if (dev->netdev_ops->ndo_neigh_destroy) +@@ -867,7 +869,7 @@ static void neigh_invalidate(struct neighbour *neigh) + neigh->ops->error_report(neigh, skb); + write_lock(&neigh->lock); + } +- skb_queue_purge(&neigh->arp_queue); ++ __skb_queue_purge(&neigh->arp_queue); + neigh->arp_queue_len_bytes = 0; + } + +@@ -1206,7 +1208,7 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, + + write_lock_bh(&neigh->lock); + } +- skb_queue_purge(&neigh->arp_queue); ++ __skb_queue_purge(&neigh->arp_queue); + neigh->arp_queue_len_bytes = 0; + } + out: +diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c +index 76f50e1..ae03b7b 100644 +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -974,7 +974,7 @@ int tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr, + struct tcp_sock *tp = tcp_sk(sk); + struct tcp_md5sig_info *md5sig; + +- key = tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&addr, AF_INET); ++ key = tcp_md5_do_lookup(sk, addr, family); + if (key) { + /* Pre-existing entry - just update that one. */ + memcpy(key->key, newkey, newkeylen); +@@ -1019,7 +1019,7 @@ int tcp_md5_do_del(struct sock *sk, const union tcp_md5_addr *addr, int family) + struct tcp_md5sig_key *key; + struct tcp_md5sig_info *md5sig; + +- key = tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&addr, AF_INET); ++ key = tcp_md5_do_lookup(sk, addr, family); + if (!key) + return -ENOENT; + hlist_del_rcu(&key->node); +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index fe14105..0b6136d 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -768,7 +768,7 @@ send: + /* + * Push out all pending data as one UDP datagram. Socket is locked. + */ +-static int udp_push_pending_frames(struct sock *sk) ++int udp_push_pending_frames(struct sock *sk) + { + struct udp_sock *up = udp_sk(sk); + struct inet_sock *inet = inet_sk(sk); +@@ -787,6 +787,7 @@ out: + up->pending = 0; + return err; + } ++EXPORT_SYMBOL(udp_push_pending_frames); + + int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, + size_t len) +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index f4fe3c0..d427f1b 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -1233,6 +1233,23 @@ try_nextdev: + } + EXPORT_SYMBOL(ipv6_dev_get_saddr); + ++int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr, ++ unsigned char banned_flags) ++{ ++ struct inet6_ifaddr *ifp; ++ int err = -EADDRNOTAVAIL; ++ ++ list_for_each_entry(ifp, &idev->addr_list, if_list) { ++ if (ifp->scope == IFA_LINK && ++ !(ifp->flags & banned_flags)) { ++ *addr = ifp->addr; ++ err = 0; ++ break; ++ } ++ } ++ return err; ++} ++ + int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, + unsigned char banned_flags) + { +@@ -1242,17 +1259,8 @@ int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, + rcu_read_lock(); + idev = __in6_dev_get(dev); + if (idev) { +- struct inet6_ifaddr *ifp; +- + read_lock_bh(&idev->lock); +- list_for_each_entry(ifp, &idev->addr_list, if_list) { +- if (ifp->scope == IFA_LINK && +- !(ifp->flags & banned_flags)) { +- *addr = ifp->addr; +- err = 0; +- break; +- } +- } ++ err = __ipv6_get_lladdr(idev, addr, banned_flags); + read_unlock_bh(&idev->lock); + } + rcu_read_unlock(); +@@ -2429,6 +2437,9 @@ static void init_loopback(struct net_device *dev) + if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE)) + continue; + ++ if (sp_ifa->rt) ++ continue; ++ + sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); + + /* Failure cases are ignored */ +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index bf290ce..d6b9d56 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -912,11 +912,17 @@ static struct dst_entry *ip6_sk_dst_check(struct sock *sk, + const struct flowi6 *fl6) + { + struct ipv6_pinfo *np = inet6_sk(sk); +- struct rt6_info *rt = (struct rt6_info *)dst; ++ struct rt6_info *rt; + + if (!dst) + goto out; + ++ if (dst->ops->family != AF_INET6) { ++ dst_release(dst); ++ return NULL; ++ } ++ ++ rt = (struct rt6_info *)dst; + /* Yes, checking route validity in not connected + * case is not very simple. Take into account, + * that we do not support routing by source, TOS, +@@ -1181,11 +1187,12 @@ static inline struct ipv6_rt_hdr *ip6_rthdr_dup(struct ipv6_rt_hdr *src, + return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL; + } + +-static void ip6_append_data_mtu(int *mtu, ++static void ip6_append_data_mtu(unsigned int *mtu, + int *maxfraglen, + unsigned int fragheaderlen, + struct sk_buff *skb, +- struct rt6_info *rt) ++ struct rt6_info *rt, ++ bool pmtuprobe) + { + if (!(rt->dst.flags & DST_XFRM_TUNNEL)) { + if (skb == NULL) { +@@ -1197,7 +1204,9 @@ static void ip6_append_data_mtu(int *mtu, + * this fragment is not first, the headers + * space is regarded as data space. + */ +- *mtu = dst_mtu(rt->dst.path); ++ *mtu = min(*mtu, pmtuprobe ? ++ rt->dst.dev->mtu : ++ dst_mtu(rt->dst.path)); + } + *maxfraglen = ((*mtu - fragheaderlen) & ~7) + + fragheaderlen - sizeof(struct frag_hdr); +@@ -1214,11 +1223,10 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, + struct ipv6_pinfo *np = inet6_sk(sk); + struct inet_cork *cork; + struct sk_buff *skb, *skb_prev = NULL; +- unsigned int maxfraglen, fragheaderlen; ++ unsigned int maxfraglen, fragheaderlen, mtu; + int exthdrlen; + int dst_exthdrlen; + int hh_len; +- int mtu; + int copy; + int err; + int offset = 0; +@@ -1381,7 +1389,9 @@ alloc_new_skb: + /* update mtu and maxfraglen if necessary */ + if (skb == NULL || skb_prev == NULL) + ip6_append_data_mtu(&mtu, &maxfraglen, +- fragheaderlen, skb, rt); ++ fragheaderlen, skb, rt, ++ np->pmtudisc == ++ IPV6_PMTUDISC_PROBE); + + skb_prev = skb; + +diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c +index b2869ca..6a4ab24 100644 +--- a/net/ipv6/mcast.c ++++ b/net/ipv6/mcast.c +@@ -1334,8 +1334,9 @@ mld_scount(struct ifmcaddr6 *pmc, int type, int gdeleted, int sdeleted) + return scount; + } + +-static struct sk_buff *mld_newpack(struct net_device *dev, int size) ++static struct sk_buff *mld_newpack(struct inet6_dev *idev, int size) + { ++ struct net_device *dev = idev->dev; + struct net *net = dev_net(dev); + struct sock *sk = net->ipv6.igmp_sk; + struct sk_buff *skb; +@@ -1360,7 +1361,7 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size) + + skb_reserve(skb, hlen); + +- if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) { ++ if (__ipv6_get_lladdr(idev, &addr_buf, IFA_F_TENTATIVE)) { + /* : + * use unspecified address as the source address + * when a valid link-local address is not available. +@@ -1456,7 +1457,7 @@ static struct sk_buff *add_grhead(struct sk_buff *skb, struct ifmcaddr6 *pmc, + struct mld2_grec *pgr; + + if (!skb) +- skb = mld_newpack(dev, dev->mtu); ++ skb = mld_newpack(pmc->idev, dev->mtu); + if (!skb) + return NULL; + pgr = (struct mld2_grec *)skb_put(skb, sizeof(struct mld2_grec)); +@@ -1476,7 +1477,8 @@ static struct sk_buff *add_grhead(struct sk_buff *skb, struct ifmcaddr6 *pmc, + static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, + int type, int gdeleted, int sdeleted) + { +- struct net_device *dev = pmc->idev->dev; ++ struct inet6_dev *idev = pmc->idev; ++ struct net_device *dev = idev->dev; + struct mld2_report *pmr; + struct mld2_grec *pgr = NULL; + struct ip6_sf_list *psf, *psf_next, *psf_prev, **psf_list; +@@ -1505,7 +1507,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, + AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) { + if (skb) + mld_sendpack(skb); +- skb = mld_newpack(dev, dev->mtu); ++ skb = mld_newpack(idev, dev->mtu); + } + } + first = 1; +@@ -1532,7 +1534,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, + pgr->grec_nsrcs = htons(scount); + if (skb) + mld_sendpack(skb); +- skb = mld_newpack(dev, dev->mtu); ++ skb = mld_newpack(idev, dev->mtu); + first = 1; + scount = 0; + } +@@ -1587,8 +1589,8 @@ static void mld_send_report(struct inet6_dev *idev, struct ifmcaddr6 *pmc) + struct sk_buff *skb = NULL; + int type; + ++ read_lock_bh(&idev->lock); + if (!pmc) { +- read_lock_bh(&idev->lock); + for (pmc=idev->mc_list; pmc; pmc=pmc->next) { + if (pmc->mca_flags & MAF_NOREPORT) + continue; +@@ -1600,7 +1602,6 @@ static void mld_send_report(struct inet6_dev *idev, struct ifmcaddr6 *pmc) + skb = add_grec(skb, pmc, type, 0, 0); + spin_unlock_bh(&pmc->mca_lock); + } +- read_unlock_bh(&idev->lock); + } else { + spin_lock_bh(&pmc->mca_lock); + if (pmc->mca_sfcount[MCAST_EXCLUDE]) +@@ -1610,6 +1611,7 @@ static void mld_send_report(struct inet6_dev *idev, struct ifmcaddr6 *pmc) + skb = add_grec(skb, pmc, type, 0, 0); + spin_unlock_bh(&pmc->mca_lock); + } ++ read_unlock_bh(&idev->lock); + if (skb) + mld_sendpack(skb); + } +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 5a272c6..016ed7c 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -1032,10 +1032,13 @@ static void ip6_link_failure(struct sk_buff *skb) + + rt = (struct rt6_info *) skb_dst(skb); + if (rt) { +- if (rt->rt6i_flags & RTF_CACHE) +- rt6_update_expires(rt, 0); +- else if (rt->rt6i_node && (rt->rt6i_flags & RTF_DEFAULT)) ++ if (rt->rt6i_flags & RTF_CACHE) { ++ dst_hold(&rt->dst); ++ if (ip6_del_rt(rt)) ++ dst_free(&rt->dst); ++ } else if (rt->rt6i_node && (rt->rt6i_flags & RTF_DEFAULT)) { + rt->rt6i_node->fn_sernum = -1; ++ } + } + } + +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c +index aa2f18b..f79bfdb 100644 +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -895,11 +895,16 @@ static int udp_v6_push_pending_frames(struct sock *sk) + struct udphdr *uh; + struct udp_sock *up = udp_sk(sk); + struct inet_sock *inet = inet_sk(sk); +- struct flowi6 *fl6 = &inet->cork.fl.u.ip6; ++ struct flowi6 *fl6; + int err = 0; + int is_udplite = IS_UDPLITE(sk); + __wsum csum = 0; + ++ if (up->pending == AF_INET) ++ return udp_push_pending_frames(sk); ++ ++ fl6 = &inet->cork.fl.u.ip6; ++ + /* Grab the skbuff where UDP header space exists. */ + if ((skb = skb_peek(&sk->sk_write_queue)) == NULL) + goto out; +diff --git a/net/key/af_key.c b/net/key/af_key.c +index 7e5d927..5bbab6a 100644 +--- a/net/key/af_key.c ++++ b/net/key/af_key.c +@@ -1705,6 +1705,7 @@ static int key_notify_sa_flush(const struct km_event *c) + hdr->sadb_msg_version = PF_KEY_V2; + hdr->sadb_msg_errno = (uint8_t) 0; + hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); ++ hdr->sadb_msg_reserved = 0; + + pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); + +@@ -2686,6 +2687,7 @@ static int key_notify_policy_flush(const struct km_event *c) + hdr->sadb_msg_version = PF_KEY_V2; + hdr->sadb_msg_errno = (uint8_t) 0; + hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); ++ hdr->sadb_msg_reserved = 0; + pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); + return 0; + +diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c +index c6dee80..b2982f4 100644 +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -1778,7 +1778,8 @@ static const struct proto_ops pppol2tp_ops = { + + static const struct pppox_proto pppol2tp_proto = { + .create = pppol2tp_create, +- .ioctl = pppol2tp_ioctl ++ .ioctl = pppol2tp_ioctl, ++ .owner = THIS_MODULE, + }; + + #ifdef CONFIG_L2TP_V3 +diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c +index a306bc6..b943e3e 100644 +--- a/net/x25/af_x25.c ++++ b/net/x25/af_x25.c +@@ -1586,11 +1586,11 @@ out_cud_release: + case SIOCX25CALLACCPTAPPRV: { + rc = -EINVAL; + lock_sock(sk); +- if (sk->sk_state != TCP_CLOSE) +- break; +- clear_bit(X25_ACCPT_APPRV_FLAG, &x25->flags); ++ if (sk->sk_state == TCP_CLOSE) { ++ clear_bit(X25_ACCPT_APPRV_FLAG, &x25->flags); ++ rc = 0; ++ } + release_sock(sk); +- rc = 0; + break; + } + +@@ -1598,14 +1598,15 @@ out_cud_release: + rc = -EINVAL; + lock_sock(sk); + if (sk->sk_state != TCP_ESTABLISHED) +- break; ++ goto out_sendcallaccpt_release; + /* must call accptapprv above */ + if (test_bit(X25_ACCPT_APPRV_FLAG, &x25->flags)) +- break; ++ goto out_sendcallaccpt_release; + x25_write_internal(sk, X25_CALL_ACCEPTED); + x25->state = X25_STATE_3; +- release_sock(sk); + rc = 0; ++out_sendcallaccpt_release: ++ release_sock(sk); + break; + } + +diff --git a/sound/soc/codecs/sgtl5000.h b/sound/soc/codecs/sgtl5000.h +index 8a9f435..d3a68bb 100644 +--- a/sound/soc/codecs/sgtl5000.h ++++ b/sound/soc/codecs/sgtl5000.h +@@ -347,7 +347,7 @@ + #define SGTL5000_PLL_INT_DIV_MASK 0xf800 + #define SGTL5000_PLL_INT_DIV_SHIFT 11 + #define SGTL5000_PLL_INT_DIV_WIDTH 5 +-#define SGTL5000_PLL_FRAC_DIV_MASK 0x0700 ++#define SGTL5000_PLL_FRAC_DIV_MASK 0x07ff + #define SGTL5000_PLL_FRAC_DIV_SHIFT 0 + #define SGTL5000_PLL_FRAC_DIV_WIDTH 11 + +diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c +index c97d05f..4da9ca9 100644 +--- a/sound/usb/6fire/pcm.c ++++ b/sound/usb/6fire/pcm.c +@@ -540,7 +540,7 @@ static snd_pcm_uframes_t usb6fire_pcm_pointer( + snd_pcm_uframes_t ret; + + if (rt->panic || !sub) +- return SNDRV_PCM_STATE_XRUN; ++ return SNDRV_PCM_POS_XRUN; + + spin_lock_irqsave(&sub->lock, flags); + ret = sub->dma_off; diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.55-56.patch b/patch/kernel/sun8i-default/0001-patch-3.4.55-56.patch new file mode 100644 index 000000000..d4b989ea6 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.55-56.patch @@ -0,0 +1,1486 @@ +diff --git a/Makefile b/Makefile +index c11116f..2fe1f6d 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 55 ++SUBLEVEL = 56 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h +index 0192a4e..80de64b 100644 +--- a/arch/powerpc/include/asm/module.h ++++ b/arch/powerpc/include/asm/module.h +@@ -87,10 +87,9 @@ struct exception_table_entry; + void sort_ex_table(struct exception_table_entry *start, + struct exception_table_entry *finish); + +-#ifdef CONFIG_MODVERSIONS ++#if defined(CONFIG_MODVERSIONS) && defined(CONFIG_PPC64) + #define ARCH_RELOCATES_KCRCTAB +- +-extern const unsigned long reloc_start[]; ++#define reloc_start PHYSICAL_START + #endif + #endif /* __KERNEL__ */ + #endif /* _ASM_POWERPC_MODULE_H */ +diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S +index 65d1c08..7703569 100644 +--- a/arch/powerpc/kernel/vmlinux.lds.S ++++ b/arch/powerpc/kernel/vmlinux.lds.S +@@ -38,9 +38,6 @@ jiffies = jiffies_64 + 4; + #endif + SECTIONS + { +- . = 0; +- reloc_start = .; +- + . = KERNELBASE; + + /* +diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h +index 011358c..2f36a66 100644 +--- a/arch/s390/include/asm/pgtable.h ++++ b/arch/s390/include/asm/pgtable.h +@@ -67,6 +67,10 @@ static inline int is_zero_pfn(unsigned long pfn) + + #define my_zero_pfn(addr) page_to_pfn(ZERO_PAGE(addr)) + ++/* TODO: s390 cannot support io_remap_pfn_range... */ ++#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ ++ remap_pfn_range(vma, vaddr, pfn, size, prot) ++ + #endif /* !__ASSEMBLY__ */ + + /* +diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c +index d985713..f81597f 100644 +--- a/drivers/acpi/acpi_memhotplug.c ++++ b/drivers/acpi/acpi_memhotplug.c +@@ -421,6 +421,7 @@ static int acpi_memory_device_add(struct acpi_device *device) + /* Get the range from the _CRS */ + result = acpi_memory_get_device_resources(mem_device); + if (result) { ++ device->driver_data = NULL; + kfree(mem_device); + return result; + } +diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig +index 6bdedd7..1ad34ed 100644 +--- a/drivers/ata/Kconfig ++++ b/drivers/ata/Kconfig +@@ -93,7 +93,7 @@ config SATA_FSL + If unsure, say N. + + config SATA_INIC162X +- tristate "Initio 162x SATA support" ++ tristate "Initio 162x SATA support (Very Experimental)" + depends on PCI + help + This option enables support for Initio 162x Serial ATA. +diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c +index 45cc02b..9dbd3ae 100644 +--- a/drivers/ata/ata_piix.c ++++ b/drivers/ata/ata_piix.c +@@ -344,7 +344,7 @@ static const struct pci_device_id piix_pci_tbl[] = { + /* SATA Controller IDE (Wellsburg) */ + { 0x8086, 0x8d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, + /* SATA Controller IDE (Wellsburg) */ +- { 0x8086, 0x8d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, ++ { 0x8086, 0x8d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_snb }, + /* SATA Controller IDE (Wellsburg) */ + { 0x8086, 0x8d60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, + /* SATA Controller IDE (Wellsburg) */ +diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c +index 5c7d70c..3a8b55e 100644 +--- a/drivers/ata/sata_inic162x.c ++++ b/drivers/ata/sata_inic162x.c +@@ -6,6 +6,18 @@ + * + * This file is released under GPL v2. + * ++ * **** WARNING **** ++ * ++ * This driver never worked properly and unfortunately data corruption is ++ * relatively common. There isn't anyone working on the driver and there's ++ * no support from the vendor. Do not use this driver in any production ++ * environment. ++ * ++ * http://thread.gmane.org/gmane.linux.debian.devel.bugs.rc/378525/focus=54491 ++ * https://bugzilla.kernel.org/show_bug.cgi?id=60565 ++ * ++ * ***************** ++ * + * This controller is eccentric and easily locks up if something isn't + * right. Documentation is available at initio's website but it only + * documents registers (not programming model). +@@ -809,6 +821,8 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) + + ata_print_version_once(&pdev->dev, DRV_VERSION); + ++ dev_alert(&pdev->dev, "inic162x support is broken with common data corruption issues and will be disabled by default, contact linux-ide@vger.kernel.org if in production use\n"); ++ + /* alloc host */ + host = ata_host_alloc_pinfo(&pdev->dev, ppi, NR_PORTS); + hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL); +diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c +index 4fd1dea..4ed7bf9 100644 +--- a/drivers/block/xen-blkback/blkback.c ++++ b/drivers/block/xen-blkback/blkback.c +@@ -399,7 +399,18 @@ static int dispatch_discard_io(struct xen_blkif *blkif, + int status = BLKIF_RSP_OKAY; + struct block_device *bdev = blkif->vbd.bdev; + unsigned long secure; ++ struct phys_req preq; ++ ++ preq.sector_number = req->u.discard.sector_number; ++ preq.nr_sects = req->u.discard.nr_sectors; + ++ err = xen_vbd_translate(&preq, blkif, WRITE); ++ if (err) { ++ pr_warn(DRV_PFX "access denied: DISCARD [%llu->%llu] on dev=%04x\n", ++ preq.sector_number, ++ preq.sector_number + preq.nr_sects, blkif->vbd.pdevice); ++ goto fail_response; ++ } + blkif->st_ds_req++; + + xen_blkif_get(blkif); +@@ -410,7 +421,7 @@ static int dispatch_discard_io(struct xen_blkif *blkif, + err = blkdev_issue_discard(bdev, req->u.discard.sector_number, + req->u.discard.nr_sectors, + GFP_KERNEL, secure); +- ++fail_response: + if (err == -EOPNOTSUPP) { + pr_debug(DRV_PFX "discard op failed, not supported\n"); + status = BLKIF_RSP_EOPNOTSUPP; +diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c +index b8e4809..b558810 100644 +--- a/drivers/firewire/core-cdev.c ++++ b/drivers/firewire/core-cdev.c +@@ -53,6 +53,7 @@ + #define FW_CDEV_KERNEL_VERSION 5 + #define FW_CDEV_VERSION_EVENT_REQUEST2 4 + #define FW_CDEV_VERSION_ALLOCATE_REGION_END 4 ++#define FW_CDEV_VERSION_AUTO_FLUSH_ISO_OVERFLOW 5 + + struct client { + u32 version; +@@ -998,6 +999,8 @@ static int ioctl_create_iso_context(struct client *client, union ioctl_arg *arg) + a->channel, a->speed, a->header_size, cb, client); + if (IS_ERR(context)) + return PTR_ERR(context); ++ if (client->version < FW_CDEV_VERSION_AUTO_FLUSH_ISO_OVERFLOW) ++ context->drop_overflow_headers = true; + + /* We only support one context at this time. */ + spin_lock_irq(&client->lock); +diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c +index 2b54600..c1de4c3 100644 +--- a/drivers/firewire/ohci.c ++++ b/drivers/firewire/ohci.c +@@ -2694,8 +2694,11 @@ static void copy_iso_headers(struct iso_context *ctx, const u32 *dma_hdr) + { + u32 *ctx_hdr; + +- if (ctx->header_length + ctx->base.header_size > PAGE_SIZE) ++ if (ctx->header_length + ctx->base.header_size > PAGE_SIZE) { ++ if (ctx->base.drop_overflow_headers) ++ return; + flush_iso_completions(ctx); ++ } + + ctx_hdr = ctx->header + ctx->header_length; + ctx->last_timestamp = (u16)le32_to_cpu((__force __le32)dma_hdr[0]); +@@ -2855,8 +2858,11 @@ static int handle_it_packet(struct context *context, + + sync_it_packet_for_cpu(context, d); + +- if (ctx->header_length + 4 > PAGE_SIZE) ++ if (ctx->header_length + 4 > PAGE_SIZE) { ++ if (ctx->base.drop_overflow_headers) ++ return 1; + flush_iso_completions(ctx); ++ } + + ctx_hdr = ctx->header + ctx->header_length; + ctx->last_timestamp = le16_to_cpu(last->res_count); +diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c +index 43672b6..daa1e34 100644 +--- a/drivers/gpu/drm/radeon/atom.c ++++ b/drivers/gpu/drm/radeon/atom.c +@@ -1222,12 +1222,17 @@ int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) + int r; + + mutex_lock(&ctx->mutex); ++ /* reset data block */ ++ ctx->data_block = 0; + /* reset reg block */ + ctx->reg_block = 0; + /* reset fb window */ + ctx->fb_base = 0; + /* reset io mode */ + ctx->io_mode = ATOM_IO_MM; ++ /* reset divmul */ ++ ctx->divmul[0] = 0; ++ ctx->divmul[1] = 0; + r = atom_execute_table_locked(ctx, index, params); + mutex_unlock(&ctx->mutex); + return r; +diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c +index 886b41f..505f27e 100644 +--- a/drivers/gpu/drm/radeon/atombios_dp.c ++++ b/drivers/gpu/drm/radeon/atombios_dp.c +@@ -45,6 +45,41 @@ static char *pre_emph_names[] = { + }; + + /***** radeon AUX functions *****/ ++ ++/* Atom needs data in little endian format ++ * so swap as appropriate when copying data to ++ * or from atom. Note that atom operates on ++ * dw units. ++ */ ++static void radeon_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le) ++{ ++#ifdef __BIG_ENDIAN ++ u8 src_tmp[20], dst_tmp[20]; /* used for byteswapping */ ++ u32 *dst32, *src32; ++ int i; ++ ++ memcpy(src_tmp, src, num_bytes); ++ src32 = (u32 *)src_tmp; ++ dst32 = (u32 *)dst_tmp; ++ if (to_le) { ++ for (i = 0; i < ((num_bytes + 3) / 4); i++) ++ dst32[i] = cpu_to_le32(src32[i]); ++ memcpy(dst, dst_tmp, num_bytes); ++ } else { ++ u8 dws = num_bytes & ~3; ++ for (i = 0; i < ((num_bytes + 3) / 4); i++) ++ dst32[i] = le32_to_cpu(src32[i]); ++ memcpy(dst, dst_tmp, dws); ++ if (num_bytes % 4) { ++ for (i = 0; i < (num_bytes % 4); i++) ++ dst[dws+i] = dst_tmp[dws+i]; ++ } ++ } ++#else ++ memcpy(dst, src, num_bytes); ++#endif ++} ++ + union aux_channel_transaction { + PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION v1; + PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 v2; +@@ -66,10 +101,10 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan, + + base = (unsigned char *)(rdev->mode_info.atom_context->scratch + 1); + +- memcpy(base, send, send_bytes); ++ radeon_copy_swap(base, send, send_bytes, true); + +- args.v1.lpAuxRequest = 0 + 4; +- args.v1.lpDataOut = 16 + 4; ++ args.v1.lpAuxRequest = cpu_to_le16((u16)(0 + 4)); ++ args.v1.lpDataOut = cpu_to_le16((u16)(16 + 4)); + args.v1.ucDataOutLen = 0; + args.v1.ucChannelID = chan->rec.i2c_id; + args.v1.ucDelay = delay / 10; +@@ -103,7 +138,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan, + recv_bytes = recv_size; + + if (recv && recv_size) +- memcpy(recv, base + 16, recv_bytes); ++ radeon_copy_swap(recv, base + 16, recv_bytes, false); + + return recv_bytes; + } +diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c +index 2b2c557..07d0bcd 100644 +--- a/drivers/gpu/drm/radeon/radeon_combios.c ++++ b/drivers/gpu/drm/radeon/radeon_combios.c +@@ -147,7 +147,7 @@ static uint16_t combios_get_table_offset(struct drm_device *dev, + enum radeon_combios_table_offset table) + { + struct radeon_device *rdev = dev->dev_private; +- int rev; ++ int rev, size; + uint16_t offset = 0, check_offset; + + if (!rdev->bios) +@@ -156,174 +156,106 @@ static uint16_t combios_get_table_offset(struct drm_device *dev, + switch (table) { + /* absolute offset tables */ + case COMBIOS_ASIC_INIT_1_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0xc); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0xc; + break; + case COMBIOS_BIOS_SUPPORT_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x14); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x14; + break; + case COMBIOS_DAC_PROGRAMMING_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x2a); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x2a; + break; + case COMBIOS_MAX_COLOR_DEPTH_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x2c); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x2c; + break; + case COMBIOS_CRTC_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x2e); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x2e; + break; + case COMBIOS_PLL_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x30); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x30; + break; + case COMBIOS_TV_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x32); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x32; + break; + case COMBIOS_DFP_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x34); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x34; + break; + case COMBIOS_HW_CONFIG_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x36); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x36; + break; + case COMBIOS_MULTIMEDIA_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x38); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x38; + break; + case COMBIOS_TV_STD_PATCH_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x3e); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x3e; + break; + case COMBIOS_LCD_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x40); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x40; + break; + case COMBIOS_MOBILE_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x42); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x42; + break; + case COMBIOS_PLL_INIT_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x46); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x46; + break; + case COMBIOS_MEM_CONFIG_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x48); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x48; + break; + case COMBIOS_SAVE_MASK_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x4a); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x4a; + break; + case COMBIOS_HARDCODED_EDID_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x4c); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x4c; + break; + case COMBIOS_ASIC_INIT_2_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x4e); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x4e; + break; + case COMBIOS_CONNECTOR_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x50); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x50; + break; + case COMBIOS_DYN_CLK_1_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x52); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x52; + break; + case COMBIOS_RESERVED_MEM_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x54); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x54; + break; + case COMBIOS_EXT_TMDS_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x58); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x58; + break; + case COMBIOS_MEM_CLK_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x5a); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x5a; + break; + case COMBIOS_EXT_DAC_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x5c); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x5c; + break; + case COMBIOS_MISC_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x5e); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x5e; + break; + case COMBIOS_CRT_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x60); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x60; + break; + case COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x62); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x62; + break; + case COMBIOS_COMPONENT_VIDEO_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x64); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x64; + break; + case COMBIOS_FAN_SPEED_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x66); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x66; + break; + case COMBIOS_OVERDRIVE_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x68); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x68; + break; + case COMBIOS_OEM_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x6a); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x6a; + break; + case COMBIOS_DYN_CLK_2_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x6c); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x6c; + break; + case COMBIOS_POWER_CONNECTOR_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x6e); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x6e; + break; + case COMBIOS_I2C_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x70); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x70; + break; + /* relative offset tables */ + case COMBIOS_ASIC_INIT_3_TABLE: /* offset from misc info */ +@@ -439,11 +371,16 @@ static uint16_t combios_get_table_offset(struct drm_device *dev, + } + break; + default: ++ check_offset = 0; + break; + } + +- return offset; ++ size = RBIOS8(rdev->bios_header_start + 0x6); ++ /* check absolute offset tables */ ++ if (table < COMBIOS_ASIC_INIT_3_TABLE && check_offset && check_offset < size) ++ offset = RBIOS16(rdev->bios_header_start + check_offset); + ++ return offset; + } + + bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev) +@@ -953,8 +890,10 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct + dac = RBIOS8(dac_info + 0x3) & 0xf; + p_dac->ps2_pdac_adj = (bg << 8) | (dac); + } +- /* if the values are all zeros, use the table */ +- if (p_dac->ps2_pdac_adj) ++ /* if the values are zeros, use the table */ ++ if ((dac == 0) || (bg == 0)) ++ found = 0; ++ else + found = 1; + } + +diff --git a/drivers/md/dm-verity.c b/drivers/md/dm-verity.c +index 68bf5c3..9ab2a6a 100644 +--- a/drivers/md/dm-verity.c ++++ b/drivers/md/dm-verity.c +@@ -813,9 +813,8 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv) + for (i = v->levels - 1; i >= 0; i--) { + sector_t s; + v->hash_level_block[i] = hash_position; +- s = verity_position_at_level(v, v->data_blocks, i); +- s = (s >> v->hash_per_block_bits) + +- !!(s & ((1 << v->hash_per_block_bits) - 1)); ++ s = (v->data_blocks + ((sector_t)1 << ((i + 1) * v->hash_per_block_bits)) - 1) ++ >> ((i + 1) * v->hash_per_block_bits); + if (hash_position + s < hash_position) { + ti->error = "Hash device offset overflow"; + r = -E2BIG; +diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c +index 0cc7985..54ba531 100644 +--- a/drivers/md/raid10.c ++++ b/drivers/md/raid10.c +@@ -2029,12 +2029,18 @@ static void recovery_request_write(struct mddev *mddev, struct r10bio *r10_bio) + d = r10_bio->devs[1].devnum; + wbio = r10_bio->devs[1].bio; + wbio2 = r10_bio->devs[1].repl_bio; ++ /* Need to test wbio2->bi_end_io before we call ++ * generic_make_request as if the former is NULL, ++ * the latter is free to free wbio2. ++ */ ++ if (wbio2 && !wbio2->bi_end_io) ++ wbio2 = NULL; + if (wbio->bi_end_io) { + atomic_inc(&conf->mirrors[d].rdev->nr_pending); + md_sync_acct(conf->mirrors[d].rdev->bdev, wbio->bi_size >> 9); + generic_make_request(wbio); + } +- if (wbio2 && wbio2->bi_end_io) { ++ if (wbio2) { + atomic_inc(&conf->mirrors[d].replacement->nr_pending); + md_sync_acct(conf->mirrors[d].replacement->bdev, + wbio2->bi_size >> 9); +diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c +index 0240576..6155c8b 100644 +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -3326,6 +3326,7 @@ static void handle_stripe(struct stripe_head *sh) + if (test_and_clear_bit(STRIPE_SYNC_REQUESTED, &sh->state)) { + set_bit(STRIPE_SYNCING, &sh->state); + clear_bit(STRIPE_INSYNC, &sh->state); ++ clear_bit(STRIPE_REPLACED, &sh->state); + } + clear_bit(STRIPE_DELAYED, &sh->state); + +@@ -3465,19 +3466,23 @@ static void handle_stripe(struct stripe_head *sh) + handle_parity_checks5(conf, sh, &s, disks); + } + +- if (s.replacing && s.locked == 0 +- && !test_bit(STRIPE_INSYNC, &sh->state)) { ++ if ((s.replacing || s.syncing) && s.locked == 0 ++ && !test_bit(STRIPE_COMPUTE_RUN, &sh->state) ++ && !test_bit(STRIPE_REPLACED, &sh->state)) { + /* Write out to replacement devices where possible */ + for (i = 0; i < conf->raid_disks; i++) +- if (test_bit(R5_UPTODATE, &sh->dev[i].flags) && +- test_bit(R5_NeedReplace, &sh->dev[i].flags)) { ++ if (test_bit(R5_NeedReplace, &sh->dev[i].flags)) { ++ WARN_ON(!test_bit(R5_UPTODATE, &sh->dev[i].flags)); + set_bit(R5_WantReplace, &sh->dev[i].flags); + set_bit(R5_LOCKED, &sh->dev[i].flags); + s.locked++; + } +- set_bit(STRIPE_INSYNC, &sh->state); ++ if (s.replacing) ++ set_bit(STRIPE_INSYNC, &sh->state); ++ set_bit(STRIPE_REPLACED, &sh->state); + } + if ((s.syncing || s.replacing) && s.locked == 0 && ++ !test_bit(STRIPE_COMPUTE_RUN, &sh->state) && + test_bit(STRIPE_INSYNC, &sh->state)) { + md_done_sync(conf->mddev, STRIPE_SECTORS, 1); + clear_bit(STRIPE_SYNCING, &sh->state); +diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h +index 8d8e139..f1ed18e 100644 +--- a/drivers/md/raid5.h ++++ b/drivers/md/raid5.h +@@ -306,6 +306,7 @@ enum { + STRIPE_SYNC_REQUESTED, + STRIPE_SYNCING, + STRIPE_INSYNC, ++ STRIPE_REPLACED, + STRIPE_PREREAD_ACTIVE, + STRIPE_DELAYED, + STRIPE_DEGRADED, +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index cbefe67..bc177b9 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -518,7 +518,7 @@ static int virtnet_poll(struct napi_struct *napi, int budget) + { + struct virtnet_info *vi = container_of(napi, struct virtnet_info, napi); + void *buf; +- unsigned int len, received = 0; ++ unsigned int r, len, received = 0; + + again: + while (received < budget && +@@ -535,8 +535,9 @@ again: + + /* Out of packets? */ + if (received < budget) { ++ r = virtqueue_enable_cb_prepare(vi->rvq); + napi_complete(napi); +- if (unlikely(!virtqueue_enable_cb(vi->rvq)) && ++ if (unlikely(virtqueue_poll(vi->rvq, r)) && + napi_schedule_prep(napi)) { + virtqueue_disable_cb(vi->rvq); + __napi_schedule(napi); +diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c +index 4f1b10b..3743ac9 100644 +--- a/drivers/s390/scsi/zfcp_aux.c ++++ b/drivers/s390/scsi/zfcp_aux.c +@@ -3,7 +3,7 @@ + * + * Module interface and handling of zfcp data structures. + * +- * Copyright IBM Corporation 2002, 2010 ++ * Copyright IBM Corp. 2002, 2013 + */ + + /* +@@ -23,6 +23,7 @@ + * Christof Schmitt + * Martin Petermann + * Sven Schuetz ++ * Steffen Maier + */ + + #define KMSG_COMPONENT "zfcp" +@@ -415,6 +416,8 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device) + adapter->dma_parms.max_segment_size = ZFCP_QDIO_SBALE_LEN; + adapter->ccw_device->dev.dma_parms = &adapter->dma_parms; + ++ adapter->stat_read_buf_num = FSF_STATUS_READS_RECOM; ++ + if (!zfcp_scsi_adapter_register(adapter)) + return adapter; + +diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c +index 5fdf70b..961e327 100644 +--- a/drivers/s390/scsi/zfcp_fsf.c ++++ b/drivers/s390/scsi/zfcp_fsf.c +@@ -3,7 +3,7 @@ + * + * Implementation of FSF commands. + * +- * Copyright IBM Corporation 2002, 2010 ++ * Copyright IBM Corp. 2002, 2013 + */ + + #define KMSG_COMPONENT "zfcp" +@@ -483,12 +483,8 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) + + fc_host_port_name(shost) = nsp->fl_wwpn; + fc_host_node_name(shost) = nsp->fl_wwnn; +- fc_host_port_id(shost) = ntoh24(bottom->s_id); +- fc_host_speed(shost) = +- zfcp_fsf_convert_portspeed(bottom->fc_link_speed); + fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3; + +- adapter->hydra_version = bottom->adapter_type; + adapter->timer_ticks = bottom->timer_interval & ZFCP_FSF_TIMER_INT_MASK; + adapter->stat_read_buf_num = max(bottom->status_read_buf_num, + (u16)FSF_STATUS_READS_RECOM); +@@ -496,6 +492,19 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) + if (fc_host_permanent_port_name(shost) == -1) + fc_host_permanent_port_name(shost) = fc_host_port_name(shost); + ++ zfcp_scsi_set_prot(adapter); ++ ++ /* no error return above here, otherwise must fix call chains */ ++ /* do not evaluate invalid fields */ ++ if (req->qtcb->header.fsf_status == FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE) ++ return 0; ++ ++ fc_host_port_id(shost) = ntoh24(bottom->s_id); ++ fc_host_speed(shost) = ++ zfcp_fsf_convert_portspeed(bottom->fc_link_speed); ++ ++ adapter->hydra_version = bottom->adapter_type; ++ + switch (bottom->fc_topology) { + case FSF_TOPO_P2P: + adapter->peer_d_id = ntoh24(bottom->peer_d_id); +@@ -517,8 +526,6 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) + return -EIO; + } + +- zfcp_scsi_set_prot(adapter); +- + return 0; + } + +@@ -569,6 +576,8 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req) + &adapter->status); + zfcp_fsf_link_down_info_eval(req, + &qtcb->header.fsf_status_qual.link_down_info); ++ if (zfcp_fsf_exchange_config_evaluate(req)) ++ return; + break; + default: + zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh3"); +diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c +index eac9509..d99d4a0 100644 +--- a/drivers/scsi/qla2xxx/qla_iocb.c ++++ b/drivers/scsi/qla2xxx/qla_iocb.c +@@ -423,6 +423,8 @@ qla2x00_start_scsi(srb_t *sp) + __constant_cpu_to_le16(CF_SIMPLE_TAG); + break; + } ++ } else { ++ cmd_pkt->control_flags = __constant_cpu_to_le16(CF_SIMPLE_TAG); + } + + /* Load SCSI command packet. */ +@@ -1331,11 +1333,11 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, + fcp_cmnd->task_attribute = TSK_ORDERED; + break; + default: +- fcp_cmnd->task_attribute = 0; ++ fcp_cmnd->task_attribute = TSK_SIMPLE; + break; + } + } else { +- fcp_cmnd->task_attribute = 0; ++ fcp_cmnd->task_attribute = TSK_SIMPLE; + } + + cmd_pkt->fcp_rsp_dseg_len = 0; /* Let response come in status iocb */ +@@ -1541,7 +1543,12 @@ qla24xx_start_scsi(srb_t *sp) + case ORDERED_QUEUE_TAG: + cmd_pkt->task = TSK_ORDERED; + break; ++ default: ++ cmd_pkt->task = TSK_SIMPLE; ++ break; + } ++ } else { ++ cmd_pkt->task = TSK_SIMPLE; + } + + /* Load SCSI command packet. */ +diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c +index 3141c1a..105fff2 100644 +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -672,10 +672,17 @@ static int scsi_setup_flush_cmnd(struct scsi_device *sdp, struct request *rq) + + static void sd_unprep_fn(struct request_queue *q, struct request *rq) + { ++ struct scsi_cmnd *SCpnt = rq->special; ++ + if (rq->cmd_flags & REQ_DISCARD) { + free_page((unsigned long)rq->buffer); + rq->buffer = NULL; + } ++ if (SCpnt->cmnd != rq->cmd) { ++ mempool_free(SCpnt->cmnd, sd_cdb_pool); ++ SCpnt->cmnd = NULL; ++ SCpnt->cmd_len = 0; ++ } + } + + /** +@@ -1539,21 +1546,6 @@ static int sd_done(struct scsi_cmnd *SCpnt) + if (rq_data_dir(SCpnt->request) == READ && scsi_prot_sg_count(SCpnt)) + sd_dif_complete(SCpnt, good_bytes); + +- if (scsi_host_dif_capable(sdkp->device->host, sdkp->protection_type) +- == SD_DIF_TYPE2_PROTECTION && SCpnt->cmnd != SCpnt->request->cmd) { +- +- /* We have to print a failed command here as the +- * extended CDB gets freed before scsi_io_completion() +- * is called. +- */ +- if (result) +- scsi_print_command(SCpnt); +- +- mempool_free(SCpnt->cmnd, sd_cdb_pool); +- SCpnt->cmnd = NULL; +- SCpnt->cmd_len = 0; +- } +- + return good_bytes; + } + +diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c +index 3799cf1..50dc93e 100644 +--- a/drivers/staging/comedi/comedi_fops.c ++++ b/drivers/staging/comedi/comedi_fops.c +@@ -1370,6 +1370,7 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, + void *file) + { + struct comedi_subdevice *s; ++ int ret; + + if (arg >= dev->n_subdevices) + return -EINVAL; +@@ -1386,7 +1387,11 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, + if (s->busy != file) + return -EBUSY; + +- return do_cancel(dev, s); ++ ret = do_cancel(dev, s); ++ if (comedi_get_subdevice_runflags(s) & SRF_USER) ++ wake_up_interruptible(&s->async->wait_head); ++ ++ return ret; + } + + /* +diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c +index 00c58cc..facb3ad 100644 +--- a/drivers/target/iscsi/iscsi_target_configfs.c ++++ b/drivers/target/iscsi/iscsi_target_configfs.c +@@ -415,7 +415,7 @@ static ssize_t __iscsi_##prefix##_store_##name( \ + if (!capable(CAP_SYS_ADMIN)) \ + return -EPERM; \ + \ +- snprintf(auth->name, PAGE_SIZE, "%s", page); \ ++ snprintf(auth->name, sizeof(auth->name), "%s", page); \ + if (!strncmp("NULL", auth->name, 4)) \ + auth->naf_flags &= ~flags; \ + else \ +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 49b139c..a969ec1 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -488,6 +488,15 @@ resubmit: + static inline int + hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt) + { ++ /* Need to clear both directions for control ep */ ++ if (((devinfo >> 11) & USB_ENDPOINT_XFERTYPE_MASK) == ++ USB_ENDPOINT_XFER_CONTROL) { ++ int status = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), ++ HUB_CLEAR_TT_BUFFER, USB_RT_PORT, ++ devinfo ^ 0x8000, tt, NULL, 0, 1000); ++ if (status) ++ return status; ++ } + return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), + HUB_CLEAR_TT_BUFFER, USB_RT_PORT, devinfo, + tt, NULL, 0, 1000); +diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h +index 6c7945b..29a68f0a 100644 +--- a/drivers/usb/dwc3/core.h ++++ b/drivers/usb/dwc3/core.h +@@ -641,8 +641,8 @@ struct dwc3 { + + struct dwc3_event_type { + u32 is_devspec:1; +- u32 type:6; +- u32 reserved8_31:25; ++ u32 type:7; ++ u32 reserved8_31:24; + } __packed; + + #define DWC3_DEPEVT_XFERCOMPLETE 0x01 +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index f62629b..6d6fb88 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -1393,6 +1393,7 @@ err1: + __dwc3_gadget_ep_disable(dwc->eps[0]); + + err0: ++ dwc->gadget_driver = NULL; + spin_unlock_irqrestore(&dwc->lock, flags); + + return ret; +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 0f928b3..8072a93 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -1162,9 +1162,6 @@ static int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev, + } + + xhci = hcd_to_xhci(hcd); +- if (xhci->xhc_state & XHCI_STATE_HALTED) +- return -ENODEV; +- + if (check_virt_dev) { + if (!udev->slot_id || !xhci->devs[udev->slot_id]) { + printk(KERN_DEBUG "xHCI %s called with unaddressed " +@@ -1180,6 +1177,9 @@ static int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev, + } + } + ++ if (xhci->xhc_state & XHCI_STATE_HALTED) ++ return -ENODEV; ++ + return 1; + } + +@@ -4194,6 +4194,13 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) + + get_quirks(dev, xhci); + ++ /* In xhci controllers which follow xhci 1.0 spec gives a spurious ++ * success event after a short transfer. This quirk will ignore such ++ * spurious event. ++ */ ++ if (xhci->hci_version > 0x96) ++ xhci->quirks |= XHCI_SPURIOUS_SUCCESS; ++ + /* Make sure the HC is halted. */ + retval = xhci_halt(xhci); + if (retval) +diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c +index dd573ab..7af163d 100644 +--- a/drivers/usb/misc/sisusbvga/sisusb.c ++++ b/drivers/usb/misc/sisusbvga/sisusb.c +@@ -3247,6 +3247,7 @@ static const struct usb_device_id sisusb_table[] = { + { USB_DEVICE(0x0711, 0x0903) }, + { USB_DEVICE(0x0711, 0x0918) }, + { USB_DEVICE(0x0711, 0x0920) }, ++ { USB_DEVICE(0x0711, 0x0950) }, + { USB_DEVICE(0x182d, 0x021c) }, + { USB_DEVICE(0x182d, 0x0269) }, + { } +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index f8a9cd7..3e4c27d 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -745,9 +745,34 @@ static struct usb_device_id id_table_combined [] = { + { USB_DEVICE(FTDI_VID, FTDI_NDI_AURORA_SCU_PID), + .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, + { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, +- { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_SERIAL_VX7_PID) }, +- { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_CT29B_PID) }, +- { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_RTS01_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) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_57B_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29A_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29B_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29F_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_62B_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_S01_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_63_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29C_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_81B_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_82B_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_K5D_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_K4Y_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_K5G_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_S05_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_60_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_61_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_62_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_63B_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_64_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_65_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_92_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_92D_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_W5R_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_A5R_PID) }, ++ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_PW1_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) }, + { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) }, +diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h +index 6dd7925..1b8af46 100644 +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -815,11 +815,35 @@ + /* + * RT Systems programming cables for various ham radios + */ +-#define RTSYSTEMS_VID 0x2100 /* Vendor ID */ +-#define RTSYSTEMS_SERIAL_VX7_PID 0x9e52 /* Serial converter for VX-7 Radios using FT232RL */ +-#define RTSYSTEMS_CT29B_PID 0x9e54 /* CT29B Radio Cable */ +-#define RTSYSTEMS_RTS01_PID 0x9e57 /* USB-RTS01 Radio Cable */ +- ++#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 */ ++#define RTSYSTEMS_USB_57A_PID 0x9e51 /* USB-57A USB to 4pin 3.5mm plug */ ++#define RTSYSTEMS_USB_57B_PID 0x9e52 /* USB-57B USB to extended 4pin 3.5mm plug */ ++#define RTSYSTEMS_USB_29A_PID 0x9e53 /* USB-29A USB to 3.5mm stereo plug */ ++#define RTSYSTEMS_USB_29B_PID 0x9e54 /* USB-29B USB to 6 pin mini din */ ++#define RTSYSTEMS_USB_29F_PID 0x9e55 /* USB-29F USB to 6 pin modular plug */ ++#define RTSYSTEMS_USB_62B_PID 0x9e56 /* USB-62B USB to 8 pin mini din plug*/ ++#define RTSYSTEMS_USB_S01_PID 0x9e57 /* USB-RTS01 USB to 3.5 mm stereo plug*/ ++#define RTSYSTEMS_USB_63_PID 0x9e58 /* USB-63 USB to 9 pin female*/ ++#define RTSYSTEMS_USB_29C_PID 0x9e59 /* USB-29C USB to 4 pin modular plug*/ ++#define RTSYSTEMS_USB_81B_PID 0x9e5A /* USB-81 USB to 8 pin mini din plug*/ ++#define RTSYSTEMS_USB_82B_PID 0x9e5B /* USB-82 USB to 2.5 mm stereo plug*/ ++#define RTSYSTEMS_USB_K5D_PID 0x9e5C /* USB-K5D USB to 8 pin modular plug*/ ++#define RTSYSTEMS_USB_K4Y_PID 0x9e5D /* USB-K4Y USB to 2.5/3.5 mm plugs*/ ++#define RTSYSTEMS_USB_K5G_PID 0x9e5E /* USB-K5G USB to 8 pin modular plug*/ ++#define RTSYSTEMS_USB_S05_PID 0x9e5F /* USB-RTS05 USB to 2.5 mm stereo plug*/ ++#define RTSYSTEMS_USB_60_PID 0x9e60 /* USB-60 USB to 6 pin din*/ ++#define RTSYSTEMS_USB_61_PID 0x9e61 /* USB-61 USB to 6 pin mini din*/ ++#define RTSYSTEMS_USB_62_PID 0x9e62 /* USB-62 USB to 8 pin mini din*/ ++#define RTSYSTEMS_USB_63B_PID 0x9e63 /* USB-63 USB to 9 pin female*/ ++#define RTSYSTEMS_USB_64_PID 0x9e64 /* USB-64 USB to 9 pin male*/ ++#define RTSYSTEMS_USB_65_PID 0x9e65 /* USB-65 USB to 9 pin female null modem*/ ++#define RTSYSTEMS_USB_92_PID 0x9e66 /* USB-92 USB to 12 pin plug*/ ++#define RTSYSTEMS_USB_92D_PID 0x9e67 /* USB-92D USB to 12 pin plug data*/ ++#define RTSYSTEMS_USB_W5R_PID 0x9e68 /* USB-W5R USB to 8 pin modular plug*/ ++#define RTSYSTEMS_USB_A5R_PID 0x9e69 /* USB-A5R USB to 8 pin modular plug*/ ++#define RTSYSTEMS_USB_PW1_PID 0x9e6A /* USB-PW1 USB to 8 pin modular plug*/ + + /* + * Physik Instrumente +diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c +index a39a08c..a7492ba 100644 +--- a/drivers/usb/serial/ti_usb_3410_5052.c ++++ b/drivers/usb/serial/ti_usb_3410_5052.c +@@ -390,7 +390,7 @@ static int ti_startup(struct usb_serial *serial) + usb_set_serial_data(serial, tdev); + + /* determine device type */ +- if (usb_match_id(serial->interface, ti_id_table_3410)) ++ if (serial->type == &ti_1port_device) + tdev->td_is_3410 = 1; + dbg("%s - device type is %s", __func__, + tdev->td_is_3410 ? "3410" : "5052"); +diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h +index 8ee632c..cf442e0 100644 +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -657,6 +657,13 @@ UNUSUAL_DEV( 0x054c, 0x016a, 0x0000, 0x9999, + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY ), + ++/* Submitted by Ren Bigcren */ ++UNUSUAL_DEV( 0x054c, 0x02a5, 0x0100, 0x0100, ++ "Sony Corp.", ++ "MicroVault Flash Drive", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_NO_READ_CAPACITY_16 ), ++ + /* floppy reports multiple luns */ + UNUSUAL_DEV( 0x055d, 0x2020, 0x0000, 0x0210, + "SAMSUNG", +diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c +index 52bfd07..c212de7 100644 +--- a/drivers/virtio/virtio_ring.c ++++ b/drivers/virtio/virtio_ring.c +@@ -498,16 +498,18 @@ EXPORT_SYMBOL_GPL(virtqueue_disable_cb); + * virtqueue_enable_cb - restart callbacks after disable_cb. + * @vq: the struct virtqueue we're talking about. + * +- * This re-enables callbacks; it returns "false" if there are pending +- * buffers in the queue, to detect a possible race between the driver +- * checking for more work, and enabling callbacks. ++ * This re-enables callbacks; it returns current queue state ++ * in an opaque unsigned value. This value should be later tested by ++ * virtqueue_poll, to detect a possible race between the driver checking for ++ * more work, and enabling callbacks. + * + * Caller must ensure we don't call this with other virtqueue + * operations at the same time (except where noted). + */ +-bool virtqueue_enable_cb(struct virtqueue *_vq) ++unsigned virtqueue_enable_cb_prepare(struct virtqueue *_vq) + { + struct vring_virtqueue *vq = to_vvq(_vq); ++ u16 last_used_idx; + + START_USE(vq); + +@@ -517,15 +519,45 @@ bool virtqueue_enable_cb(struct virtqueue *_vq) + * either clear the flags bit or point the event index at the next + * entry. Always do both to keep code simple. */ + vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT; +- vring_used_event(&vq->vring) = vq->last_used_idx; ++ vring_used_event(&vq->vring) = last_used_idx = vq->last_used_idx; ++ END_USE(vq); ++ return last_used_idx; ++} ++EXPORT_SYMBOL_GPL(virtqueue_enable_cb_prepare); ++ ++/** ++ * virtqueue_poll - query pending used buffers ++ * @vq: the struct virtqueue we're talking about. ++ * @last_used_idx: virtqueue state (from call to virtqueue_enable_cb_prepare). ++ * ++ * Returns "true" if there are pending used buffers in the queue. ++ * ++ * This does not need to be serialized. ++ */ ++bool virtqueue_poll(struct virtqueue *_vq, unsigned last_used_idx) ++{ ++ struct vring_virtqueue *vq = to_vvq(_vq); ++ + virtio_mb(vq); +- if (unlikely(more_used(vq))) { +- END_USE(vq); +- return false; +- } ++ return (u16)last_used_idx != vq->vring.used->idx; ++} ++EXPORT_SYMBOL_GPL(virtqueue_poll); + +- END_USE(vq); +- return true; ++/** ++ * virtqueue_enable_cb - restart callbacks after disable_cb. ++ * @vq: the struct virtqueue we're talking about. ++ * ++ * This re-enables callbacks; it returns "false" if there are pending ++ * buffers in the queue, to detect a possible race between the driver ++ * checking for more work, and enabling callbacks. ++ * ++ * Caller must ensure we don't call this with other virtqueue ++ * operations at the same time (except where noted). ++ */ ++bool virtqueue_enable_cb(struct virtqueue *_vq) ++{ ++ unsigned last_used_idx = virtqueue_enable_cb_prepare(_vq); ++ return !virtqueue_poll(_vq, last_used_idx); + } + EXPORT_SYMBOL_GPL(virtqueue_enable_cb); + +diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c +index b2db77e..82b27d4 100644 +--- a/drivers/xen/evtchn.c ++++ b/drivers/xen/evtchn.c +@@ -377,18 +377,12 @@ static long evtchn_ioctl(struct file *file, + if (unbind.port >= NR_EVENT_CHANNELS) + break; + +- spin_lock_irq(&port_user_lock); +- + rc = -ENOTCONN; +- if (get_port_user(unbind.port) != u) { +- spin_unlock_irq(&port_user_lock); ++ if (get_port_user(unbind.port) != u) + break; +- } + + disable_irq(irq_from_evtchn(unbind.port)); + +- spin_unlock_irq(&port_user_lock); +- + evtchn_unbind_from_user(u, unbind.port); + + rc = 0; +@@ -488,26 +482,15 @@ static int evtchn_release(struct inode *inode, struct file *filp) + int i; + struct per_user_data *u = filp->private_data; + +- spin_lock_irq(&port_user_lock); +- +- free_page((unsigned long)u->ring); +- + for (i = 0; i < NR_EVENT_CHANNELS; i++) { + if (get_port_user(i) != u) + continue; + + disable_irq(irq_from_evtchn(i)); +- } +- +- spin_unlock_irq(&port_user_lock); +- +- for (i = 0; i < NR_EVENT_CHANNELS; i++) { +- if (get_port_user(i) != u) +- continue; +- + evtchn_unbind_from_user(get_port_user(i), i); + } + ++ free_page((unsigned long)u->ring); + kfree(u->name); + kfree(u); + +diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c +index fef1f21..c4f0a99 100644 +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -6846,6 +6846,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, + int err = 0; + int ret; + int level; ++ bool root_dropped = false; + + path = btrfs_alloc_path(); + if (!path) { +@@ -6903,6 +6904,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, + while (1) { + btrfs_tree_lock(path->nodes[level]); + btrfs_set_lock_blocking(path->nodes[level]); ++ path->locks[level] = BTRFS_WRITE_LOCK_BLOCKING; + + ret = btrfs_lookup_extent_info(trans, root, + path->nodes[level]->start, +@@ -6919,6 +6921,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, + break; + + btrfs_tree_unlock(path->nodes[level]); ++ path->locks[level] = 0; + WARN_ON(wc->refs[level] != 1); + level--; + } +@@ -7014,12 +7017,22 @@ int btrfs_drop_snapshot(struct btrfs_root *root, + free_extent_buffer(root->commit_root); + kfree(root); + } ++ root_dropped = true; + out_end_trans: + btrfs_end_transaction_throttle(trans, tree_root); + out_free: + kfree(wc); + btrfs_free_path(path); + out: ++ /* ++ * So if we need to stop dropping the snapshot for whatever reason we ++ * need to make sure to add it back to the dead root list so that we ++ * keep trying to do the work later. This also cleans up roots if we ++ * don't have it in the radix (like when we recover after a power fail ++ * or unmount) so we don't leak memory. ++ */ ++ if (root_dropped == false) ++ btrfs_add_dead_root(root); + if (err) + btrfs_std_error(root->fs_info, err); + return err; +diff --git a/fs/super.c b/fs/super.c +index cf00177..3c520a5 100644 +--- a/fs/super.c ++++ b/fs/super.c +@@ -298,19 +298,19 @@ EXPORT_SYMBOL(deactivate_super); + * and want to turn it into a full-blown active reference. grab_super() + * is called with sb_lock held and drops it. Returns 1 in case of + * success, 0 if we had failed (superblock contents was already dead or +- * dying when grab_super() had been called). ++ * dying when grab_super() had been called). Note that this is only ++ * called for superblocks not in rundown mode (== ones still on ->fs_supers ++ * of their type), so increment of ->s_count is OK here. + */ + static int grab_super(struct super_block *s) __releases(sb_lock) + { +- if (atomic_inc_not_zero(&s->s_active)) { +- spin_unlock(&sb_lock); +- return 1; +- } +- /* it's going away */ + s->s_count++; + spin_unlock(&sb_lock); +- /* wait for it to die */ + down_write(&s->s_umount); ++ if ((s->s_flags & MS_BORN) && atomic_inc_not_zero(&s->s_active)) { ++ put_super(s); ++ return 1; ++ } + up_write(&s->s_umount); + put_super(s); + return 0; +@@ -440,11 +440,6 @@ retry: + destroy_super(s); + s = NULL; + } +- down_write(&old->s_umount); +- if (unlikely(!(old->s_flags & MS_BORN))) { +- deactivate_locked_super(old); +- goto retry; +- } + return old; + } + } +@@ -677,10 +672,10 @@ restart: + if (hlist_unhashed(&sb->s_instances)) + continue; + if (sb->s_bdev == bdev) { +- if (grab_super(sb)) /* drops sb_lock */ +- return sb; +- else ++ if (!grab_super(sb)) + goto restart; ++ up_write(&sb->s_umount); ++ return sb; + } + } + spin_unlock(&sb_lock); +diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h +index d500369..1db453e 100644 +--- a/include/linux/firewire-cdev.h ++++ b/include/linux/firewire-cdev.h +@@ -215,8 +215,8 @@ struct fw_cdev_event_request2 { + * with the %FW_CDEV_ISO_INTERRUPT bit set, when explicitly requested with + * %FW_CDEV_IOC_FLUSH_ISO, or when there have been so many completed packets + * without the interrupt bit set that the kernel's internal buffer for @header +- * is about to overflow. (In the last case, kernels with ABI version < 5 drop +- * header data up to the next interrupt packet.) ++ * is about to overflow. (In the last case, ABI versions < 5 drop header data ++ * up to the next interrupt packet.) + * + * Isochronous transmit events (context type %FW_CDEV_ISO_CONTEXT_TRANSMIT): + * +diff --git a/include/linux/firewire.h b/include/linux/firewire.h +index cdc9b71..4d259fc 100644 +--- a/include/linux/firewire.h ++++ b/include/linux/firewire.h +@@ -409,6 +409,7 @@ struct fw_iso_context { + int type; + int channel; + int speed; ++ bool drop_overflow_headers; + size_t header_size; + union { + fw_iso_callback_t sc; +diff --git a/include/linux/virtio.h b/include/linux/virtio.h +index 8efd28a..2b779bf 100644 +--- a/include/linux/virtio.h ++++ b/include/linux/virtio.h +@@ -44,6 +44,10 @@ void virtqueue_disable_cb(struct virtqueue *vq); + + bool virtqueue_enable_cb(struct virtqueue *vq); + ++unsigned virtqueue_enable_cb_prepare(struct virtqueue *vq); ++ ++bool virtqueue_poll(struct virtqueue *vq, unsigned); ++ + bool virtqueue_enable_cb_delayed(struct virtqueue *vq); + + void *virtqueue_detach_unused_buf(struct virtqueue *vq); +diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c +index e675182..c9ce09a 100644 +--- a/kernel/trace/trace_syscalls.c ++++ b/kernel/trace/trace_syscalls.c +@@ -358,6 +358,9 @@ void ftrace_syscall_exit(void *ignore, struct pt_regs *regs, long ret) + if (!sys_data) + return; + ++ local_save_flags(irq_flags); ++ pc = preempt_count(); ++ + event = trace_current_buffer_lock_reserve(&buffer, + sys_data->exit_event->event.type, sizeof(*entry), + irq_flags, pc); +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index 533ea80..8090542 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -5592,4 +5592,10 @@ __offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn) + zone->free_area[order].nr_free--; ++ __mod_zone_page_state(zone, NR_FREE_PAGES, ++ - (1UL << order)); ++#ifdef CONFIG_HIGHMEM ++ if (PageHighMem(page)) ++ totalhigh_pages -= 1 << order; ++#endif + for (i = 0; i < (1 << order); i++) + SetPageReserved((page+i)); + pfn += (1 << order); +diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c +index 4790568..8df4597 100644 +--- a/sound/soc/codecs/max98088.c ++++ b/sound/soc/codecs/max98088.c +@@ -1594,7 +1594,7 @@ static int max98088_dai2_digital_mute(struct snd_soc_dai *codec_dai, int mute) + + static void max98088_sync_cache(struct snd_soc_codec *codec) + { +- u16 *reg_cache = codec->reg_cache; ++ u8 *reg_cache = codec->reg_cache; + int i; + + if (!codec->cache_sync) +diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c +index 96f6f9f..e96c6ed 100644 +--- a/sound/soc/codecs/wm8962.c ++++ b/sound/soc/codecs/wm8962.c +@@ -1599,7 +1599,6 @@ static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) + { + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); +- u16 *reg_cache = codec->reg_cache; + int ret; + + /* Apply the update (if any) */ +@@ -1608,16 +1607,19 @@ static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol, + return 0; + + /* If the left PGA is enabled hit that VU bit... */ +- if (snd_soc_read(codec, WM8962_PWR_MGMT_2) & WM8962_HPOUTL_PGA_ENA) +- return snd_soc_write(codec, WM8962_HPOUTL_VOLUME, +- reg_cache[WM8962_HPOUTL_VOLUME]); ++ ret = snd_soc_read(codec, WM8962_PWR_MGMT_2); ++ if (ret & WM8962_HPOUTL_PGA_ENA) { ++ snd_soc_write(codec, WM8962_HPOUTL_VOLUME, ++ snd_soc_read(codec, WM8962_HPOUTL_VOLUME)); ++ return 1; ++ } + + /* ...otherwise the right. The VU is stereo. */ +- if (snd_soc_read(codec, WM8962_PWR_MGMT_2) & WM8962_HPOUTR_PGA_ENA) +- return snd_soc_write(codec, WM8962_HPOUTR_VOLUME, +- reg_cache[WM8962_HPOUTR_VOLUME]); ++ if (ret & WM8962_HPOUTR_PGA_ENA) ++ snd_soc_write(codec, WM8962_HPOUTR_VOLUME, ++ snd_soc_read(codec, WM8962_HPOUTR_VOLUME)); + +- return 0; ++ return 1; + } + + /* The VU bits for the speakers are in a different register to the mute +@@ -3363,7 +3365,6 @@ static int wm8962_probe(struct snd_soc_codec *codec) + int ret; + struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); + struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); +- u16 *reg_cache = codec->reg_cache; + int i, trigger, irq_pol; + bool dmicclk, dmicdat; + +@@ -3421,8 +3422,9 @@ static int wm8962_probe(struct snd_soc_codec *codec) + + /* Put the speakers into mono mode? */ + if (pdata->spk_mono) +- reg_cache[WM8962_CLASS_D_CONTROL_2] +- |= WM8962_SPK_MONO; ++ snd_soc_update_bits(codec, WM8962_CLASS_D_CONTROL_2, ++ WM8962_SPK_MONO_MASK, WM8962_SPK_MONO); ++ + + /* Micbias setup, detection enable and detection + * threasholds. */ diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.56-57.patch b/patch/kernel/sun8i-default/0001-patch-3.4.56-57.patch new file mode 100644 index 000000000..2c403786a --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.56-57.patch @@ -0,0 +1,743 @@ +diff --git a/Makefile b/Makefile +index 2fe1f6d..7f4df0c 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 56 ++SUBLEVEL = 57 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c +index 2d6e649..6610e81 100644 +--- a/arch/x86/kernel/i387.c ++++ b/arch/x86/kernel/i387.c +@@ -132,7 +132,7 @@ static void __cpuinit mxcsr_feature_mask_init(void) + clts(); + if (cpu_has_fxsr) { + memset(&fx_scratch, 0, sizeof(struct i387_fxsave_struct)); +- asm volatile("fxsave %0" : : "m" (fx_scratch)); ++ asm volatile("fxsave %0" : "+m" (fx_scratch)); + mask = fx_scratch.mxcsr_mask; + if (mask == 0) + mask = 0x0000ffbf; +diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c +index 6ea287e2..9bdfcf5 100644 +--- a/drivers/acpi/battery.c ++++ b/drivers/acpi/battery.c +@@ -117,6 +117,7 @@ struct acpi_battery { + struct acpi_device *device; + struct notifier_block pm_nb; + unsigned long update_time; ++ int revision; + int rate_now; + int capacity_now; + int voltage_now; +@@ -350,6 +351,7 @@ static struct acpi_offsets info_offsets[] = { + }; + + static struct acpi_offsets extended_info_offsets[] = { ++ {offsetof(struct acpi_battery, revision), 0}, + {offsetof(struct acpi_battery, power_unit), 0}, + {offsetof(struct acpi_battery, design_capacity), 0}, + {offsetof(struct acpi_battery, full_charge_capacity), 0}, +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 45c5cf8..232119a 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -296,6 +296,7 @@ enum intel_pch { + + #define QUIRK_PIPEA_FORCE (1<<0) + #define QUIRK_LVDS_SSC_DISABLE (1<<1) ++#define QUIRK_NO_PCH_PWM_ENABLE (1<<2) + + struct intel_fbdev; + struct intel_fbc_work; +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 84867a8..0e35922 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -9160,6 +9160,17 @@ static void quirk_ssc_force_disable(struct drm_device *dev) + dev_priv->quirks |= QUIRK_LVDS_SSC_DISABLE; + } + ++/* ++ * Some machines (Dell XPS13) suffer broken backlight controls if ++ * BLM_PCH_PWM_ENABLE is set. ++ */ ++static void quirk_no_pcm_pwm_enable(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ dev_priv->quirks |= QUIRK_NO_PCH_PWM_ENABLE; ++ DRM_INFO("applying no-PCH_PWM_ENABLE quirk\n"); ++} ++ + struct intel_quirk { + int device; + int subsystem_vendor; +@@ -9192,6 +9203,11 @@ struct intel_quirk intel_quirks[] = { + + /* Sony Vaio Y cannot use SSC on LVDS */ + { 0x0046, 0x104d, 0x9076, quirk_ssc_force_disable }, ++ ++ /* Dell XPS13 HD Sandy Bridge */ ++ { 0x0116, 0x1028, 0x052e, quirk_no_pcm_pwm_enable }, ++ /* Dell XPS13 HD and XPS13 FHD Ivy Bridge */ ++ { 0x0166, 0x1028, 0x058b, quirk_no_pcm_pwm_enable }, + }; + + static void intel_init_quirks(struct drm_device *dev) +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index 207180d..ab4d990 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -1097,7 +1097,8 @@ bool intel_lvds_init(struct drm_device *dev) + goto failed; + + out: +- if (HAS_PCH_SPLIT(dev)) { ++ if (HAS_PCH_SPLIT(dev) && ++ !(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) { + u32 pwm; + + pipe = (I915_READ(PCH_LVDS) & LVDS_PIPEB_SELECT) ? 1 : 0; +diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c +index a746ba2..a956053 100644 +--- a/drivers/net/arcnet/arcnet.c ++++ b/drivers/net/arcnet/arcnet.c +@@ -1007,7 +1007,7 @@ static void arcnet_rx(struct net_device *dev, int bufnum) + + soft = &pkt.soft.rfc1201; + +- lp->hw.copy_from_card(dev, bufnum, 0, &pkt, sizeof(ARC_HDR_SIZE)); ++ lp->hw.copy_from_card(dev, bufnum, 0, &pkt, ARC_HDR_SIZE); + if (pkt.hard.offset[0]) { + ofs = pkt.hard.offset[0]; + length = 256 - ofs; +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c +index d3695ed..a061e37 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c +@@ -108,9 +108,8 @@ s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, + + /* Enable arbiter */ + reg &= ~IXGBE_DPMCS_ARBDIS; +- /* Enable DFP and Recycle mode */ +- reg |= (IXGBE_DPMCS_TDPAC | IXGBE_DPMCS_TRM); + reg |= IXGBE_DPMCS_TSOEF; ++ + /* Configure Max TSO packet size 34KB including payload and headers */ + reg |= (0x4 << IXGBE_DPMCS_MTSOS_SHIFT); + +diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c +index 4ce981c..2205db7 100644 +--- a/drivers/net/ethernet/realtek/8139cp.c ++++ b/drivers/net/ethernet/realtek/8139cp.c +@@ -478,7 +478,7 @@ rx_status_loop: + + while (1) { + u32 status, len; +- dma_addr_t mapping; ++ dma_addr_t mapping, new_mapping; + struct sk_buff *skb, *new_skb; + struct cp_desc *desc; + const unsigned buflen = cp->rx_buf_sz; +@@ -520,6 +520,13 @@ rx_status_loop: + goto rx_next; + } + ++ new_mapping = dma_map_single(&cp->pdev->dev, new_skb->data, buflen, ++ PCI_DMA_FROMDEVICE); ++ if (dma_mapping_error(&cp->pdev->dev, new_mapping)) { ++ dev->stats.rx_dropped++; ++ goto rx_next; ++ } ++ + dma_unmap_single(&cp->pdev->dev, mapping, + buflen, PCI_DMA_FROMDEVICE); + +@@ -531,12 +538,11 @@ rx_status_loop: + + skb_put(skb, len); + +- mapping = dma_map_single(&cp->pdev->dev, new_skb->data, buflen, +- PCI_DMA_FROMDEVICE); + cp->rx_skb[rx_tail] = new_skb; + + cp_rx_skb(cp, skb, desc); + rx++; ++ mapping = new_mapping; + + rx_next: + cp->rx_ring[rx_tail].opts2 = 0; +@@ -704,6 +710,22 @@ static inline u32 cp_tx_vlan_tag(struct sk_buff *skb) + TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00; + } + ++static void unwind_tx_frag_mapping(struct cp_private *cp, struct sk_buff *skb, ++ int first, int entry_last) ++{ ++ int frag, index; ++ struct cp_desc *txd; ++ skb_frag_t *this_frag; ++ for (frag = 0; frag+first < entry_last; frag++) { ++ index = first+frag; ++ cp->tx_skb[index] = NULL; ++ txd = &cp->tx_ring[index]; ++ this_frag = &skb_shinfo(skb)->frags[frag]; ++ dma_unmap_single(&cp->pdev->dev, le64_to_cpu(txd->addr), ++ skb_frag_size(this_frag), PCI_DMA_TODEVICE); ++ } ++} ++ + static netdev_tx_t cp_start_xmit (struct sk_buff *skb, + struct net_device *dev) + { +@@ -737,6 +759,9 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb, + + len = skb->len; + mapping = dma_map_single(&cp->pdev->dev, skb->data, len, PCI_DMA_TODEVICE); ++ if (dma_mapping_error(&cp->pdev->dev, mapping)) ++ goto out_dma_error; ++ + txd->opts2 = opts2; + txd->addr = cpu_to_le64(mapping); + wmb(); +@@ -774,6 +799,9 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb, + first_len = skb_headlen(skb); + first_mapping = dma_map_single(&cp->pdev->dev, skb->data, + first_len, PCI_DMA_TODEVICE); ++ if (dma_mapping_error(&cp->pdev->dev, first_mapping)) ++ goto out_dma_error; ++ + cp->tx_skb[entry] = skb; + entry = NEXT_TX(entry); + +@@ -787,6 +815,11 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb, + mapping = dma_map_single(&cp->pdev->dev, + skb_frag_address(this_frag), + len, PCI_DMA_TODEVICE); ++ if (dma_mapping_error(&cp->pdev->dev, mapping)) { ++ unwind_tx_frag_mapping(cp, skb, first_entry, entry); ++ goto out_dma_error; ++ } ++ + eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; + + ctrl = eor | len | DescOwn; +@@ -845,11 +878,16 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb, + if (TX_BUFFS_AVAIL(cp) <= (MAX_SKB_FRAGS + 1)) + netif_stop_queue(dev); + ++out_unlock: + spin_unlock_irqrestore(&cp->lock, intr_flags); + + cpw8(TxPoll, NormalTxPoll); + + return NETDEV_TX_OK; ++out_dma_error: ++ kfree_skb(skb); ++ cp->dev->stats.tx_dropped++; ++ goto out_unlock; + } + + /* Set or clear the multicast filter for this adaptor. +@@ -1020,6 +1058,10 @@ static int cp_refill_rx(struct cp_private *cp) + + mapping = dma_map_single(&cp->pdev->dev, skb->data, + cp->rx_buf_sz, PCI_DMA_FROMDEVICE); ++ if (dma_mapping_error(&cp->pdev->dev, mapping)) { ++ kfree_skb(skb); ++ goto err_out; ++ } + cp->rx_skb[i] = skb; + + cp->rx_ring[i].opts2 = 0; +diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c +index 5caba55..d89747a 100644 +--- a/drivers/net/usb/smsc75xx.c ++++ b/drivers/net/usb/smsc75xx.c +@@ -43,7 +43,6 @@ + #define EEPROM_MAC_OFFSET (0x01) + #define DEFAULT_TX_CSUM_ENABLE (true) + #define DEFAULT_RX_CSUM_ENABLE (true) +-#define DEFAULT_TSO_ENABLE (true) + #define SMSC75XX_INTERNAL_PHY_ID (1) + #define SMSC75XX_TX_OVERHEAD (8) + #define MAX_RX_FIFO_SIZE (20 * 1024) +@@ -1049,17 +1048,14 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) + + INIT_WORK(&pdata->set_multicast, smsc75xx_deferred_multicast_write); + +- if (DEFAULT_TX_CSUM_ENABLE) { ++ if (DEFAULT_TX_CSUM_ENABLE) + dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; +- if (DEFAULT_TSO_ENABLE) +- dev->net->features |= NETIF_F_SG | +- NETIF_F_TSO | NETIF_F_TSO6; +- } ++ + if (DEFAULT_RX_CSUM_ENABLE) + dev->net->features |= NETIF_F_RXCSUM; + + dev->net->hw_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | +- NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_RXCSUM; ++ NETIF_F_RXCSUM; + + /* Init all registers */ + ret = smsc75xx_reset(dev); +@@ -1184,8 +1180,6 @@ static struct sk_buff *smsc75xx_tx_fixup(struct usbnet *dev, + { + u32 tx_cmd_a, tx_cmd_b; + +- skb_linearize(skb); +- + if (skb_headroom(skb) < SMSC75XX_TX_OVERHEAD) { + struct sk_buff *skb2 = + skb_copy_expand(skb, SMSC75XX_TX_OVERHEAD, 0, flags); +diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c +index 41c5237..2b8406a 100644 +--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c ++++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c +@@ -821,6 +821,7 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, + if (error != 0) + goto err_rx; + ++ ath9k_hw_disable(priv->ah); + #ifdef CONFIG_MAC80211_LEDS + /* must be initialized before ieee80211_register_hw */ + priv->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(priv->hw, +diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c +index 7d00a87..4be8ccc 100644 +--- a/drivers/net/wireless/mwifiex/sdio.c ++++ b/drivers/net/wireless/mwifiex/sdio.c +@@ -1449,8 +1449,8 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, + /* Allocate buffer and copy payload */ + blk_size = MWIFIEX_SDIO_BLOCK_SIZE; + buf_block_len = (pkt_len + blk_size - 1) / blk_size; +- *(u16 *) &payload[0] = (u16) pkt_len; +- *(u16 *) &payload[2] = type; ++ *(__le16 *)&payload[0] = cpu_to_le16((u16)pkt_len); ++ *(__le16 *)&payload[2] = cpu_to_le16(type); + + /* + * This is SDIO specific header +diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c +index 50f92d5..4d792a2 100644 +--- a/drivers/net/wireless/rt2x00/rt2x00queue.c ++++ b/drivers/net/wireless/rt2x00/rt2x00queue.c +@@ -856,13 +856,8 @@ void rt2x00queue_index_inc(struct queue_entry *entry, enum queue_index index) + spin_unlock_irqrestore(&queue->index_lock, irqflags); + } + +-void rt2x00queue_pause_queue(struct data_queue *queue) ++void rt2x00queue_pause_queue_nocheck(struct data_queue *queue) + { +- if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) || +- !test_bit(QUEUE_STARTED, &queue->flags) || +- test_and_set_bit(QUEUE_PAUSED, &queue->flags)) +- return; +- + switch (queue->qid) { + case QID_AC_VO: + case QID_AC_VI: +@@ -878,6 +873,15 @@ void rt2x00queue_pause_queue(struct data_queue *queue) + break; + } + } ++void rt2x00queue_pause_queue(struct data_queue *queue) ++{ ++ if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) || ++ !test_bit(QUEUE_STARTED, &queue->flags) || ++ test_and_set_bit(QUEUE_PAUSED, &queue->flags)) ++ return; ++ ++ rt2x00queue_pause_queue_nocheck(queue); ++} + EXPORT_SYMBOL_GPL(rt2x00queue_pause_queue); + + void rt2x00queue_unpause_queue(struct data_queue *queue) +@@ -939,7 +943,7 @@ void rt2x00queue_stop_queue(struct data_queue *queue) + return; + } + +- rt2x00queue_pause_queue(queue); ++ rt2x00queue_pause_queue_nocheck(queue); + + queue->rt2x00dev->ops->lib->stop_queue(queue); + +diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c +index 039c054..c75b27b 100644 +--- a/drivers/tty/serial/mxs-auart.c ++++ b/drivers/tty/serial/mxs-auart.c +@@ -375,11 +375,18 @@ static void mxs_auart_settermios(struct uart_port *u, + + static irqreturn_t mxs_auart_irq_handle(int irq, void *context) + { +- u32 istatus, istat; ++ u32 istat; + struct mxs_auart_port *s = context; + u32 stat = readl(s->port.membase + AUART_STAT); + +- istatus = istat = readl(s->port.membase + AUART_INTR); ++ istat = readl(s->port.membase + AUART_INTR); ++ ++ /* ack irq */ ++ writel(istat & (AUART_INTR_RTIS ++ | AUART_INTR_TXIS ++ | AUART_INTR_RXIS ++ | AUART_INTR_CTSMIS), ++ s->port.membase + AUART_INTR_CLR); + + if (istat & AUART_INTR_CTSMIS) { + uart_handle_cts_change(&s->port, stat & AUART_STAT_CTS); +@@ -398,12 +405,6 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context) + istat &= ~AUART_INTR_TXIS; + } + +- writel(istatus & (AUART_INTR_RTIS +- | AUART_INTR_TXIS +- | AUART_INTR_RXIS +- | AUART_INTR_CTSMIS), +- s->port.membase + AUART_INTR_CLR); +- + return IRQ_HANDLED; + } + +@@ -543,7 +544,7 @@ auart_console_write(struct console *co, const char *str, unsigned int count) + struct mxs_auart_port *s; + struct uart_port *port; + unsigned int old_ctrl0, old_ctrl2; +- unsigned int to = 1000; ++ unsigned int to = 20000; + + if (co->index > MXS_AUART_PORTS || co->index < 0) + return; +@@ -564,18 +565,23 @@ auart_console_write(struct console *co, const char *str, unsigned int count) + + uart_console_write(port, str, count, mxs_auart_console_putchar); + +- /* +- * Finally, wait for transmitter to become empty +- * and restore the TCR +- */ ++ /* Finally, wait for transmitter to become empty ... */ + while (readl(port->membase + AUART_STAT) & AUART_STAT_BUSY) { ++ udelay(1); + if (!to--) + break; +- udelay(1); + } + +- writel(old_ctrl0, port->membase + AUART_CTRL0); +- writel(old_ctrl2, port->membase + AUART_CTRL2); ++ /* ++ * ... and restore the TCR if we waited long enough for the transmitter ++ * to be idle. This might keep the transmitter enabled although it is ++ * unused, but that is better than to disable it while it is still ++ * transmitting. ++ */ ++ if (!(readl(port->membase + AUART_STAT) & AUART_STAT_BUSY)) { ++ writel(old_ctrl0, port->membase + AUART_CTRL0); ++ writel(old_ctrl2, port->membase + AUART_CTRL2); ++ } + + clk_disable(s->clk); + } +diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c +index 3568c8a..48bc91d 100644 +--- a/fs/notify/fanotify/fanotify_user.c ++++ b/fs/notify/fanotify/fanotify_user.c +@@ -120,6 +120,7 @@ static int fill_event_metadata(struct fsnotify_group *group, + metadata->event_len = FAN_EVENT_METADATA_LEN; + metadata->metadata_len = FAN_EVENT_METADATA_LEN; + metadata->vers = FANOTIFY_METADATA_VERSION; ++ metadata->reserved = 0; + metadata->mask = event->mask & FAN_ALL_OUTGOING_EVENTS; + metadata->pid = pid_vnr(event->tgid); + if (unlikely(event->mask & FAN_Q_OVERFLOW)) +diff --git a/kernel/events/core.c b/kernel/events/core.c +index d074cf0..8e810ba 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -250,9 +250,9 @@ perf_cgroup_match(struct perf_event *event) + return !event->cgrp || event->cgrp == cpuctx->cgrp; + } + +-static inline void perf_get_cgroup(struct perf_event *event) ++static inline bool perf_tryget_cgroup(struct perf_event *event) + { +- css_get(&event->cgrp->css); ++ return css_tryget(&event->cgrp->css); + } + + static inline void perf_put_cgroup(struct perf_event *event) +@@ -481,7 +481,11 @@ static inline int perf_cgroup_connect(int fd, struct perf_event *event, + event->cgrp = cgrp; + + /* must be done before we fput() the file */ +- perf_get_cgroup(event); ++ if (!perf_tryget_cgroup(event)) { ++ event->cgrp = NULL; ++ ret = -ENOENT; ++ goto out; ++ } + + /* + * all events in a group must monitor +@@ -911,6 +915,15 @@ list_add_event(struct perf_event *event, struct perf_event_context *ctx) + } + + /* ++ * Initialize event state based on the perf_event_attr::disabled. ++ */ ++static inline void perf_event__state_init(struct perf_event *event) ++{ ++ event->state = event->attr.disabled ? PERF_EVENT_STATE_OFF : ++ PERF_EVENT_STATE_INACTIVE; ++} ++ ++/* + * Called at perf_event creation and when events are attached/detached from a + * group. + */ +@@ -6058,8 +6071,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, + event->overflow_handler = overflow_handler; + event->overflow_handler_context = context; + +- if (attr->disabled) +- event->state = PERF_EVENT_STATE_OFF; ++ perf_event__state_init(event); + + pmu = NULL; + +@@ -6481,9 +6493,17 @@ SYSCALL_DEFINE5(perf_event_open, + + mutex_lock(&gctx->mutex); + perf_remove_from_context(group_leader); ++ ++ /* ++ * Removing from the context ends up with disabled ++ * event. What we want here is event in the initial ++ * startup state, ready to be add into new context. ++ */ ++ perf_event__state_init(group_leader); + list_for_each_entry(sibling, &group_leader->sibling_list, + group_entry) { + perf_remove_from_context(sibling); ++ perf_event__state_init(sibling); + put_ctx(gctx); + } + mutex_unlock(&gctx->mutex); +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index e955364..da4512f 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -5511,7 +5511,7 @@ static unsigned int get_rr_interval_fair(struct rq *rq, struct task_struct *task + * idle runqueue: + */ + if (rq->cfs.load.weight) +- rr_interval = NS_TO_JIFFIES(sched_slice(&rq->cfs, se)); ++ rr_interval = NS_TO_JIFFIES(sched_slice(cfs_rq_of(se), se)); + + return rr_interval; + } +diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c +index bf7a604..086c973 100644 +--- a/net/ipv4/sysctl_net_ipv4.c ++++ b/net/ipv4/sysctl_net_ipv4.c +@@ -34,6 +34,8 @@ static int tcp_adv_win_scale_min = -31; + static int tcp_adv_win_scale_max = 31; + static int ip_ttl_min = 1; + static int ip_ttl_max = 255; ++static int tcp_syn_retries_min = 1; ++static int tcp_syn_retries_max = MAX_TCP_SYNCNT; + static int ip_ping_group_range_min[] = { 0, 0 }; + static int ip_ping_group_range_max[] = { GID_T_MAX, GID_T_MAX }; + +@@ -276,7 +278,9 @@ static struct ctl_table ipv4_table[] = { + .data = &sysctl_tcp_syn_retries, + .maxlen = sizeof(int), + .mode = 0644, +- .proc_handler = proc_dointvec ++ .proc_handler = proc_dointvec_minmax, ++ .extra1 = &tcp_syn_retries_min, ++ .extra2 = &tcp_syn_retries_max + }, + { + .procname = "tcp_synack_retries", +diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c +index 8110362..d5e4615 100644 +--- a/net/ipv6/ip6mr.c ++++ b/net/ipv6/ip6mr.c +@@ -256,10 +256,12 @@ static void __net_exit ip6mr_rules_exit(struct net *net) + { + struct mr6_table *mrt, *next; + ++ rtnl_lock(); + list_for_each_entry_safe(mrt, next, &net->ipv6.mr6_tables, list) { + list_del(&mrt->list); + ip6mr_free_table(mrt); + } ++ rtnl_unlock(); + fib_rules_unregister(net->ipv6.mr6_rules_ops); + } + #else +@@ -286,7 +288,10 @@ static int __net_init ip6mr_rules_init(struct net *net) + + static void __net_exit ip6mr_rules_exit(struct net *net) + { ++ rtnl_lock(); + ip6mr_free_table(net->ipv6.mrt6); ++ net->ipv6.mrt6 = NULL; ++ rtnl_unlock(); + } + #endif + +diff --git a/net/key/af_key.c b/net/key/af_key.c +index 5bbab6a..60109f4 100644 +--- a/net/key/af_key.c ++++ b/net/key/af_key.c +@@ -2073,6 +2073,7 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, const struct xfrm_policy * + pol->sadb_x_policy_type = IPSEC_POLICY_NONE; + } + pol->sadb_x_policy_dir = dir+1; ++ pol->sadb_x_policy_reserved = 0; + pol->sadb_x_policy_id = xp->index; + pol->sadb_x_policy_priority = xp->priority; + +@@ -3108,7 +3109,9 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct + pol->sadb_x_policy_exttype = SADB_X_EXT_POLICY; + pol->sadb_x_policy_type = IPSEC_POLICY_IPSEC; + pol->sadb_x_policy_dir = dir+1; ++ pol->sadb_x_policy_reserved = 0; + pol->sadb_x_policy_id = xp->index; ++ pol->sadb_x_policy_priority = xp->priority; + + /* Set sadb_comb's. */ + if (x->id.proto == IPPROTO_AH) +@@ -3496,6 +3499,7 @@ static int pfkey_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, + pol->sadb_x_policy_exttype = SADB_X_EXT_POLICY; + pol->sadb_x_policy_type = IPSEC_POLICY_IPSEC; + pol->sadb_x_policy_dir = dir + 1; ++ pol->sadb_x_policy_reserved = 0; + pol->sadb_x_policy_id = 0; + pol->sadb_x_policy_priority = 0; + +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index 8ce9feb..067aa2a 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -831,8 +831,14 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); + +- /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */ +- if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) { ++ /* ++ * Drop duplicate 802.11 retransmissions ++ * (IEEE 802.11-2012: 9.3.2.10 "Duplicate detection and recovery") ++ */ ++ if (rx->skb->len >= 24 && rx->sta && ++ !ieee80211_is_ctl(hdr->frame_control) && ++ !ieee80211_is_qos_nullfunc(hdr->frame_control) && ++ !is_multicast_ether_addr(hdr->addr1)) { + if (unlikely(ieee80211_has_retry(hdr->frame_control) && + rx->sta->last_seq_ctrl[rx->seqno_idx] == + hdr->seq_ctrl)) { +diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c +index e25e490..6e38ef0 100644 +--- a/net/sched/sch_atm.c ++++ b/net/sched/sch_atm.c +@@ -606,6 +606,7 @@ static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl, + struct sockaddr_atmpvc pvc; + int state; + ++ memset(&pvc, 0, sizeof(pvc)); + pvc.sap_family = AF_ATMPVC; + pvc.sap_addr.itf = flow->vcc->dev ? flow->vcc->dev->number : -1; + pvc.sap_addr.vpi = flow->vcc->vpi; +diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c +index b7cddb9..7f59944 100644 +--- a/net/sched/sch_cbq.c ++++ b/net/sched/sch_cbq.c +@@ -1467,6 +1467,7 @@ static int cbq_dump_wrr(struct sk_buff *skb, struct cbq_class *cl) + unsigned char *b = skb_tail_pointer(skb); + struct tc_cbq_wrropt opt; + ++ memset(&opt, 0, sizeof(opt)); + opt.flags = 0; + opt.allot = cl->allot; + opt.priority = cl->priority + 1; +diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c +index 96eb168..3dd7207 100644 +--- a/net/sctp/outqueue.c ++++ b/net/sctp/outqueue.c +@@ -205,6 +205,8 @@ static inline int sctp_cacc_skip(struct sctp_transport *primary, + */ + void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q) + { ++ memset(q, 0, sizeof(struct sctp_outq)); ++ + q->asoc = asoc; + INIT_LIST_HEAD(&q->out_chunk_list); + INIT_LIST_HEAD(&q->control_chunk_list); +@@ -212,13 +214,7 @@ void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q) + INIT_LIST_HEAD(&q->sacked); + INIT_LIST_HEAD(&q->abandoned); + +- q->fast_rtx = 0; +- q->outstanding_bytes = 0; + q->empty = 1; +- q->cork = 0; +- +- q->malloced = 0; +- q->out_qlen = 0; + } + + /* Free the outqueue structure and any related pending chunks. +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index f432c57..add9f94 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -5081,12 +5081,14 @@ EXPORT_SYMBOL(cfg80211_testmode_alloc_event_skb); + + void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp) + { ++ struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0]; + void *hdr = ((void **)skb->cb)[1]; + struct nlattr *data = ((void **)skb->cb)[2]; + + nla_nest_end(skb, data); + genlmsg_end(skb, hdr); +- genlmsg_multicast(skb, 0, nl80211_testmode_mcgrp.id, gfp); ++ genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), skb, 0, ++ nl80211_testmode_mcgrp.id, gfp); + } + EXPORT_SYMBOL(cfg80211_testmode_event); + #endif +@@ -7768,7 +7770,8 @@ void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev, + + genlmsg_end(msg, hdr); + +- genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); ++ genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, ++ nl80211_mlme_mcgrp.id, gfp); + return; + + nla_put_failure: +diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c +index a58cf35..84717ce 100644 +--- a/sound/core/compress_offload.c ++++ b/sound/core/compress_offload.c +@@ -582,7 +582,7 @@ static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg) + mutex_lock(&stream->device->lock); + switch (_IOC_NR(cmd)) { + case _IOC_NR(SNDRV_COMPRESS_IOCTL_VERSION): +- put_user(SNDRV_COMPRESS_VERSION, ++ retval = put_user(SNDRV_COMPRESS_VERSION, + (int __user *)arg) ? -EFAULT : 0; + break; + case _IOC_NR(SNDRV_COMPRESS_GET_CAPS): diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.57-58.patch b/patch/kernel/sun8i-default/0001-patch-3.4.57-58.patch new file mode 100644 index 000000000..da170c7f2 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.57-58.patch @@ -0,0 +1,509 @@ +diff --git a/Makefile b/Makefile +index 7f4df0c..b19d508 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 57 ++SUBLEVEL = 58 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c +index f77e341..0cd2d50 100644 +--- a/drivers/char/virtio_console.c ++++ b/drivers/char/virtio_console.c +@@ -256,9 +256,12 @@ static struct port *find_port_by_devt_in_portdev(struct ports_device *portdev, + unsigned long flags; + + spin_lock_irqsave(&portdev->ports_lock, flags); +- list_for_each_entry(port, &portdev->ports, list) +- if (port->cdev->dev == dev) ++ list_for_each_entry(port, &portdev->ports, list) { ++ if (port->cdev->dev == dev) { ++ kref_get(&port->kref); + goto out; ++ } ++ } + port = NULL; + out: + spin_unlock_irqrestore(&portdev->ports_lock, flags); +@@ -630,6 +633,10 @@ static ssize_t port_fops_read(struct file *filp, char __user *ubuf, + + port = filp->private_data; + ++ /* Port is hot-unplugged. */ ++ if (!port->guest_connected) ++ return -ENODEV; ++ + if (!port_has_data(port)) { + /* + * If nothing's connected on the host just return 0 in +@@ -646,7 +653,7 @@ static ssize_t port_fops_read(struct file *filp, char __user *ubuf, + if (ret < 0) + return ret; + } +- /* Port got hot-unplugged. */ ++ /* Port got hot-unplugged while we were waiting above. */ + if (!port->guest_connected) + return -ENODEV; + /* +@@ -789,14 +796,14 @@ static int port_fops_open(struct inode *inode, struct file *filp) + struct port *port; + int ret; + ++ /* We get the port with a kref here */ + port = find_port_by_devt(cdev->dev); ++ if (!port) { ++ /* Port was unplugged before we could proceed */ ++ return -ENXIO; ++ } + filp->private_data = port; + +- /* Prevent against a port getting hot-unplugged at the same time */ +- spin_lock_irq(&port->portdev->ports_lock); +- kref_get(&port->kref); +- spin_unlock_irq(&port->portdev->ports_lock); +- + /* + * Don't allow opening of console port devices -- that's done + * via /dev/hvc +@@ -1254,14 +1261,6 @@ static void remove_port(struct kref *kref) + + port = container_of(kref, struct port, kref); + +- sysfs_remove_group(&port->dev->kobj, &port_attribute_group); +- device_destroy(pdrvdata.class, port->dev->devt); +- cdev_del(port->cdev); +- +- kfree(port->name); +- +- debugfs_remove(port->debugfs_file); +- + kfree(port); + } + +@@ -1291,12 +1290,14 @@ static void unplug_port(struct port *port) + spin_unlock_irq(&port->portdev->ports_lock); + + if (port->guest_connected) { ++ /* Let the app know the port is going down. */ ++ send_sigio_to_port(port); ++ ++ /* Do this after sigio is actually sent */ + port->guest_connected = false; + port->host_connected = false; +- wake_up_interruptible(&port->waitqueue); + +- /* Let the app know the port is going down. */ +- send_sigio_to_port(port); ++ wake_up_interruptible(&port->waitqueue); + } + + if (is_console_port(port)) { +@@ -1315,6 +1316,14 @@ static void unplug_port(struct port *port) + */ + port->portdev = NULL; + ++ sysfs_remove_group(&port->dev->kobj, &port_attribute_group); ++ device_destroy(pdrvdata.class, port->dev->devt); ++ cdev_del(port->cdev); ++ ++ kfree(port->name); ++ ++ debugfs_remove(port->debugfs_file); ++ + /* + * Locks around here are not necessary - a port can't be + * opened after we removed the port struct from ports_list +diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c +index 54ec8905..034085d 100644 +--- a/drivers/hwmon/adt7470.c ++++ b/drivers/hwmon/adt7470.c +@@ -215,7 +215,7 @@ static inline int adt7470_write_word_data(struct i2c_client *client, u8 reg, + u16 value) + { + return i2c_smbus_write_byte_data(client, reg, value & 0xFF) +- && i2c_smbus_write_byte_data(client, reg + 1, value >> 8); ++ || i2c_smbus_write_byte_data(client, reg + 1, value >> 8); + } + + static void adt7470_init_client(struct i2c_client *client) +diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c +index 073d5ad..7926162 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_base.c ++++ b/drivers/scsi/megaraid/megaraid_sas_base.c +@@ -3493,11 +3493,21 @@ static int megasas_init_fw(struct megasas_instance *instance) + break; + } + +- /* +- * We expect the FW state to be READY +- */ +- if (megasas_transition_to_ready(instance, 0)) +- goto fail_ready_state; ++ if (megasas_transition_to_ready(instance, 0)) { ++ atomic_set(&instance->fw_reset_no_pci_access, 1); ++ instance->instancet->adp_reset ++ (instance, instance->reg_set); ++ atomic_set(&instance->fw_reset_no_pci_access, 0); ++ dev_info(&instance->pdev->dev, ++ "megasas: FW restarted successfully from %s!\n", ++ __func__); ++ ++ /*waitting for about 30 second before retry*/ ++ ssleep(30); ++ ++ if (megasas_transition_to_ready(instance, 0)) ++ goto fail_ready_state; ++ } + + /* Check if MSI-X is supported while in ready state */ + msix_enable = (instance->instancet->read_fw_status_reg(reg_set) & +diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c +index 62b6168..e705ed3 100644 +--- a/drivers/scsi/nsp32.c ++++ b/drivers/scsi/nsp32.c +@@ -2926,7 +2926,7 @@ static void nsp32_do_bus_reset(nsp32_hw_data *data) + * reset SCSI bus + */ + nsp32_write1(base, SCSI_BUS_CONTROL, BUSCTL_RST); +- udelay(RESET_HOLD_TIME); ++ mdelay(RESET_HOLD_TIME / 1000); + nsp32_write1(base, SCSI_BUS_CONTROL, 0); + for(i = 0; i < 5; i++) { + intrdat = nsp32_read2(base, IRQ_STATUS); /* dummy read */ +diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c +index 07322ec..29fabff 100644 +--- a/drivers/scsi/scsi.c ++++ b/drivers/scsi/scsi.c +@@ -1025,6 +1025,9 @@ int scsi_get_vpd_page(struct scsi_device *sdev, u8 page, unsigned char *buf, + { + int i, result; + ++ if (sdev->skip_vpd_pages) ++ goto fail; ++ + /* Ask for all the pages supported by this device */ + result = scsi_vpd_inquiry(sdev, buf, 0, buf_len); + if (result) +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index a969ec1..aa54fad 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -3890,7 +3890,8 @@ static void hub_events(void) + hub->hdev->children[i - 1]; + + dev_dbg(hub_dev, "warm reset port %d\n", i); +- if (!udev) { ++ if (!udev || !(portstatus & ++ USB_PORT_STAT_CONNECTION)) { + status = hub_port_reset(hub, i, + NULL, HUB_BH_RESET_TIME, + true); +@@ -3900,8 +3901,8 @@ static void hub_events(void) + usb_lock_device(udev); + status = usb_reset_device(udev); + usb_unlock_device(udev); ++ connect_change = 0; + } +- connect_change = 0; + } + + if (connect_change) +diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c +index 6d0c62a..6dd3b61 100644 +--- a/fs/cifs/cifsencrypt.c ++++ b/fs/cifs/cifsencrypt.c +@@ -369,7 +369,7 @@ find_domain_name(struct cifs_ses *ses, const struct nls_table *nls_cp) + if (blobptr + attrsize > blobend) + break; + if (type == NTLMSSP_AV_NB_DOMAIN_NAME) { +- if (!attrsize) ++ if (!attrsize || attrsize >= CIFS_MAX_DOMAINNAME_LEN) + break; + if (!ses->domainName) { + ses->domainName = +diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h +index 73fea28..a5fcf19 100644 +--- a/fs/cifs/cifsglob.h ++++ b/fs/cifs/cifsglob.h +@@ -38,6 +38,7 @@ + #define MAX_TREE_SIZE (2 + MAX_SERVER_SIZE + 1 + MAX_SHARE_SIZE + 1) + #define MAX_SERVER_SIZE 15 + #define MAX_SHARE_SIZE 80 ++#define CIFS_MAX_DOMAINNAME_LEN 256 /* max domain name length */ + #define MAX_USERNAME_SIZE 256 /* reasonable maximum for current servers */ + #define MAX_PASSWORD_SIZE 512 /* max for windows seems to be 256 wide chars */ + +diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c +index 9cc574c..e7fe81d 100644 +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -1698,7 +1698,8 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, + if (string == NULL) + goto out_nomem; + +- if (strnlen(string, 256) == 256) { ++ if (strnlen(string, CIFS_MAX_DOMAINNAME_LEN) ++ == CIFS_MAX_DOMAINNAME_LEN) { + printk(KERN_WARNING "CIFS: domain name too" + " long\n"); + goto cifs_parse_mount_err; +@@ -2356,8 +2357,8 @@ cifs_put_smb_ses(struct cifs_ses *ses) + + #ifdef CONFIG_KEYS + +-/* strlen("cifs:a:") + INET6_ADDRSTRLEN + 1 */ +-#define CIFSCREDS_DESC_SIZE (7 + INET6_ADDRSTRLEN + 1) ++/* strlen("cifs:a:") + CIFS_MAX_DOMAINNAME_LEN + 1 */ ++#define CIFSCREDS_DESC_SIZE (7 + CIFS_MAX_DOMAINNAME_LEN + 1) + + /* Populate username and pw fields from keyring if possible */ + static int +diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c +index 551d0c2..de9b1c1 100644 +--- a/fs/cifs/sess.c ++++ b/fs/cifs/sess.c +@@ -198,7 +198,7 @@ static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses, + bytes_ret = 0; + } else + bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, ses->domainName, +- 256, nls_cp); ++ CIFS_MAX_DOMAINNAME_LEN, nls_cp); + bcc_ptr += 2 * bytes_ret; + bcc_ptr += 2; /* account for null terminator */ + +@@ -256,8 +256,8 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses, + + /* copy domain */ + if (ses->domainName != NULL) { +- strncpy(bcc_ptr, ses->domainName, 256); +- bcc_ptr += strnlen(ses->domainName, 256); ++ strncpy(bcc_ptr, ses->domainName, CIFS_MAX_DOMAINNAME_LEN); ++ bcc_ptr += strnlen(ses->domainName, CIFS_MAX_DOMAINNAME_LEN); + } /* else we will send a null domain name + so the server will default to its own domain */ + *bcc_ptr = 0; +diff --git a/fs/dcache.c b/fs/dcache.c +index e498de2..9d39de4 100644 +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -1556,7 +1556,7 @@ EXPORT_SYMBOL(d_find_any_alias); + */ + struct dentry *d_obtain_alias(struct inode *inode) + { +- static const struct qstr anonstring = { .name = "" }; ++ static const struct qstr anonstring = { .name = "/", .len = 1 }; + struct dentry *tmp; + struct dentry *res; + +diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c +index b80bc84..9dc6e76 100644 +--- a/fs/debugfs/inode.c ++++ b/fs/debugfs/inode.c +@@ -527,8 +527,7 @@ EXPORT_SYMBOL_GPL(debugfs_remove); + */ + void debugfs_remove_recursive(struct dentry *dentry) + { +- struct dentry *child; +- struct dentry *parent; ++ struct dentry *child, *next, *parent; + + if (!dentry) + return; +@@ -538,61 +537,37 @@ void debugfs_remove_recursive(struct dentry *dentry) + return; + + parent = dentry; ++ down: + mutex_lock(&parent->d_inode->i_mutex); ++ list_for_each_entry_safe(child, next, &parent->d_subdirs, d_u.d_child) { ++ if (!debugfs_positive(child)) ++ continue; + +- while (1) { +- /* +- * When all dentries under "parent" has been removed, +- * walk up the tree until we reach our starting point. +- */ +- if (list_empty(&parent->d_subdirs)) { +- mutex_unlock(&parent->d_inode->i_mutex); +- if (parent == dentry) +- break; +- parent = parent->d_parent; +- mutex_lock(&parent->d_inode->i_mutex); +- } +- child = list_entry(parent->d_subdirs.next, struct dentry, +- d_u.d_child); +- next_sibling: +- +- /* +- * If "child" isn't empty, walk down the tree and +- * remove all its descendants first. +- */ ++ /* perhaps simple_empty(child) makes more sense */ + if (!list_empty(&child->d_subdirs)) { + mutex_unlock(&parent->d_inode->i_mutex); + parent = child; +- mutex_lock(&parent->d_inode->i_mutex); +- continue; ++ goto down; + } +- __debugfs_remove(child, parent); +- if (parent->d_subdirs.next == &child->d_u.d_child) { +- /* +- * Try the next sibling. +- */ +- if (child->d_u.d_child.next != &parent->d_subdirs) { +- child = list_entry(child->d_u.d_child.next, +- struct dentry, +- d_u.d_child); +- goto next_sibling; +- } +- +- /* +- * Avoid infinite loop if we fail to remove +- * one dentry. +- */ +- mutex_unlock(&parent->d_inode->i_mutex); +- break; +- } +- simple_release_fs(&debugfs_mount, &debugfs_mount_count); ++ up: ++ if (!__debugfs_remove(child, parent)) ++ simple_release_fs(&debugfs_mount, &debugfs_mount_count); + } + +- parent = dentry->d_parent; ++ mutex_unlock(&parent->d_inode->i_mutex); ++ child = parent; ++ parent = parent->d_parent; + mutex_lock(&parent->d_inode->i_mutex); +- __debugfs_remove(dentry, parent); ++ ++ if (child != dentry) { ++ next = list_entry(child->d_u.d_child.next, struct dentry, ++ d_u.d_child); ++ goto up; ++ } ++ ++ if (!__debugfs_remove(child, parent)) ++ simple_release_fs(&debugfs_mount, &debugfs_mount_count); + mutex_unlock(&parent->d_inode->i_mutex); +- simple_release_fs(&debugfs_mount, &debugfs_mount_count); + } + EXPORT_SYMBOL_GPL(debugfs_remove_recursive); + +diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c +index e42b468..b1c3f2a 100644 +--- a/fs/ext4/ialloc.c ++++ b/fs/ext4/ialloc.c +@@ -687,11 +687,8 @@ repeat_in_this_group: + ino = ext4_find_next_zero_bit((unsigned long *) + inode_bitmap_bh->b_data, + EXT4_INODES_PER_GROUP(sb), ino); +- if (ino >= EXT4_INODES_PER_GROUP(sb)) { +- if (++group == ngroups) +- group = 0; +- continue; +- } ++ if (ino >= EXT4_INODES_PER_GROUP(sb)) ++ goto next_group; + if (group == 0 && (ino+1) < EXT4_FIRST_INO(sb)) { + ext4_error(sb, "reserved inode found cleared - " + "inode=%lu", ino + 1); +@@ -709,6 +706,9 @@ repeat_in_this_group: + goto got; /* we grabbed the inode! */ + if (ino < EXT4_INODES_PER_GROUP(sb)) + goto repeat_in_this_group; ++next_group: ++ if (++group == ngroups) ++ group = 0; + } + err = -ENOSPC; + goto out; +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index b93de81..8bbb14c 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -3232,7 +3232,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) + } + if (test_opt(sb, DIOREAD_NOLOCK)) { + ext4_msg(sb, KERN_ERR, "can't mount with " +- "both data=journal and delalloc"); ++ "both data=journal and dioread_nolock"); + goto failed_mount; + } + if (test_opt(sb, DELALLOC)) +@@ -4397,6 +4397,21 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) + goto restore_opts; + } + ++ if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { ++ if (test_opt2(sb, EXPLICIT_DELALLOC)) { ++ ext4_msg(sb, KERN_ERR, "can't mount with " ++ "both data=journal and delalloc"); ++ err = -EINVAL; ++ goto restore_opts; ++ } ++ if (test_opt(sb, DIOREAD_NOLOCK)) { ++ ext4_msg(sb, KERN_ERR, "can't mount with " ++ "both data=journal and dioread_nolock"); ++ err = -EINVAL; ++ goto restore_opts; ++ } ++ } ++ + if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED) + ext4_abort(sb, "Abort forced by user"); + +diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h +index 176a939..16cad53 100644 +--- a/include/linux/ftrace_event.h ++++ b/include/linux/ftrace_event.h +@@ -71,6 +71,8 @@ struct trace_iterator { + /* trace_seq for __print_flags() and __print_symbolic() etc. */ + struct trace_seq tmp_seq; + ++ cpumask_var_t started; ++ + /* The below is zeroed out in pipe_read */ + struct trace_seq seq; + struct trace_entry *ent; +@@ -83,7 +85,7 @@ struct trace_iterator { + loff_t pos; + long idx; + +- cpumask_var_t started; ++ /* All new field here will be zeroed out in pipe_read */ + }; + + +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index 13cd224..5dd9626 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -3478,6 +3478,7 @@ waitagain: + memset(&iter->seq, 0, + sizeof(struct trace_iterator) - + offsetof(struct trace_iterator, seq)); ++ cpumask_clear(iter->started); + iter->pos = -1; + + trace_event_read_lock(); +diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c +index 35ae568..9593f27 100644 +--- a/tools/perf/util/map.c ++++ b/tools/perf/util/map.c +@@ -15,7 +15,8 @@ const char *map_type__name[MAP__NR_TYPES] = { + + static inline int is_anon_memory(const char *filename) + { +- return strcmp(filename, "//anon") == 0; ++ return !strcmp(filename, "//anon") || ++ !strcmp(filename, "/anon_hugepage (deleted)"); + } + + static inline int is_no_dso_memory(const char *filename) diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.58-59.patch b/patch/kernel/sun8i-default/0001-patch-3.4.58-59.patch new file mode 100644 index 000000000..b670bde11 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.58-59.patch @@ -0,0 +1,1094 @@ +diff --git a/Makefile b/Makefile +index b19d508..efa1453 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 58 ++SUBLEVEL = 59 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/alpha/Makefile b/arch/alpha/Makefile +index 4759fe7..2cc3cc5 100644 +--- a/arch/alpha/Makefile ++++ b/arch/alpha/Makefile +@@ -12,7 +12,7 @@ NM := $(NM) -B + + LDFLAGS_vmlinux := -static -N #-relax + CHECKFLAGS += -D__alpha__ -m64 +-cflags-y := -pipe -mno-fp-regs -ffixed-8 -msmall-data ++cflags-y := -pipe -mno-fp-regs -ffixed-8 + cflags-y += $(call cc-option, -fno-jump-tables) + + cpuflags-$(CONFIG_ALPHA_EV4) := -mcpu=ev4 +diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c +index a99ed7a..ac73066 100644 +--- a/arch/arm/kernel/perf_event.c ++++ b/arch/arm/kernel/perf_event.c +@@ -109,7 +109,12 @@ armpmu_map_cache_event(const unsigned (*cache_map) + static int + armpmu_map_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config) + { +- int mapping = (*event_map)[config]; ++ int mapping; ++ ++ if (config >= PERF_COUNT_HW_MAX) ++ return -ENOENT; ++ ++ mapping = (*event_map)[config]; + return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping; + } + +@@ -319,6 +324,9 @@ validate_event(struct pmu_hw_events *hw_events, + struct hw_perf_event fake_event = event->hw; + struct pmu *leader_pmu = event->group_leader->pmu; + ++ if (is_software_event(event)) ++ return 1; ++ + if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF) + return 1; + +diff --git a/arch/cris/arch-v10/lib/Makefile b/arch/cris/arch-v10/lib/Makefile +index 36e9a9c..725153e 100644 +--- a/arch/cris/arch-v10/lib/Makefile ++++ b/arch/cris/arch-v10/lib/Makefile +@@ -2,8 +2,5 @@ + # Makefile for Etrax-specific library files.. + # + +- +-EXTRA_AFLAGS := -traditional +- + lib-y = checksum.o checksumcopy.o string.o usercopy.o memset.o csumcpfruser.o + +diff --git a/arch/cris/include/asm/posix_types.h b/arch/cris/include/asm/posix_types.h +index 72b3cd6..234891c 100644 +--- a/arch/cris/include/asm/posix_types.h ++++ b/arch/cris/include/asm/posix_types.h +@@ -33,4 +33,6 @@ typedef int __kernel_ptrdiff_t; + typedef unsigned short __kernel_old_dev_t; + #define __kernel_old_dev_t __kernel_old_dev_t + ++#include ++ + #endif /* __ARCH_CRIS_POSIX_TYPES_H */ +diff --git a/arch/cris/kernel/vmlinux.lds.S b/arch/cris/kernel/vmlinux.lds.S +index a6990cb..a68b983 100644 +--- a/arch/cris/kernel/vmlinux.lds.S ++++ b/arch/cris/kernel/vmlinux.lds.S +@@ -52,6 +52,7 @@ SECTIONS + + EXCEPTION_TABLE(4) + ++ _sdata = .; + RODATA + + . = ALIGN (4); +diff --git a/arch/frv/include/asm/thread_info.h b/arch/frv/include/asm/thread_info.h +index 92d83ea..aaea388 100644 +--- a/arch/frv/include/asm/thread_info.h ++++ b/arch/frv/include/asm/thread_info.h +@@ -21,8 +21,6 @@ + + #define THREAD_SIZE 8192 + +-#define __HAVE_ARCH_TASK_STRUCT_ALLOCATOR +- + /* + * low level task data that entry.S needs immediate access to + * - this struct should fit entirely inside of one cache line +diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c +index 3941cbc..c4dc7a4 100644 +--- a/arch/frv/kernel/process.c ++++ b/arch/frv/kernel/process.c +@@ -44,21 +44,6 @@ asmlinkage void ret_from_fork(void); + void (*pm_power_off)(void); + EXPORT_SYMBOL(pm_power_off); + +-struct task_struct *alloc_task_struct_node(int node) +-{ +- struct task_struct *p = kmalloc_node(THREAD_SIZE, GFP_KERNEL, node); +- +- if (p) +- atomic_set((atomic_t *)(p+1), 1); +- return p; +-} +- +-void free_task_struct(struct task_struct *p) +-{ +- if (atomic_dec_and_test((atomic_t *)(p+1))) +- kfree(p); +-} +- + static void core_sleep_idle(void) + { + #ifdef LED_DEBUG_SLEEP +diff --git a/arch/m68k/emu/natfeat.c b/arch/m68k/emu/natfeat.c +index 2291a7d..fa277ae 100644 +--- a/arch/m68k/emu/natfeat.c ++++ b/arch/m68k/emu/natfeat.c +@@ -18,9 +18,11 @@ + #include + #include + ++extern long nf_get_id2(const char *feature_name); ++ + asm("\n" +-" .global nf_get_id,nf_call\n" +-"nf_get_id:\n" ++" .global nf_get_id2,nf_call\n" ++"nf_get_id2:\n" + " .short 0x7300\n" + " rts\n" + "nf_call:\n" +@@ -29,12 +31,25 @@ asm("\n" + "1: moveq.l #0,%d0\n" + " rts\n" + " .section __ex_table,\"a\"\n" +-" .long nf_get_id,1b\n" ++" .long nf_get_id2,1b\n" + " .long nf_call,1b\n" + " .previous"); +-EXPORT_SYMBOL_GPL(nf_get_id); + EXPORT_SYMBOL_GPL(nf_call); + ++long nf_get_id(const char *feature_name) ++{ ++ /* feature_name may be in vmalloc()ed memory, so make a copy */ ++ char name_copy[32]; ++ size_t n; ++ ++ n = strlcpy(name_copy, feature_name, sizeof(name_copy)); ++ if (n >= sizeof(name_copy)) ++ return 0; ++ ++ return nf_get_id2(name_copy); ++} ++EXPORT_SYMBOL_GPL(nf_get_id); ++ + void nfprint(const char *fmt, ...) + { + static char buf[256]; +diff --git a/arch/m68k/include/asm/div64.h b/arch/m68k/include/asm/div64.h +index 444ea8a..ef881cf 100644 +--- a/arch/m68k/include/asm/div64.h ++++ b/arch/m68k/include/asm/div64.h +@@ -15,16 +15,17 @@ + unsigned long long n64; \ + } __n; \ + unsigned long __rem, __upper; \ ++ unsigned long __base = (base); \ + \ + __n.n64 = (n); \ + if ((__upper = __n.n32[0])) { \ + asm ("divul.l %2,%1:%0" \ +- : "=d" (__n.n32[0]), "=d" (__upper) \ +- : "d" (base), "0" (__n.n32[0])); \ ++ : "=d" (__n.n32[0]), "=d" (__upper) \ ++ : "d" (__base), "0" (__n.n32[0])); \ + } \ + asm ("divu.l %2,%1:%0" \ +- : "=d" (__n.n32[1]), "=d" (__rem) \ +- : "d" (base), "1" (__upper), "0" (__n.n32[1])); \ ++ : "=d" (__n.n32[1]), "=d" (__rem) \ ++ : "d" (__base), "1" (__upper), "0" (__n.n32[1])); \ + (n) = __n.n64; \ + __rem; \ + }) +diff --git a/arch/microblaze/configs/mmu_defconfig b/arch/microblaze/configs/mmu_defconfig +index b3f5eec..a470f57 100644 +--- a/arch/microblaze/configs/mmu_defconfig ++++ b/arch/microblaze/configs/mmu_defconfig +@@ -1,25 +1,22 @@ + CONFIG_EXPERIMENTAL=y + CONFIG_SYSVIPC=y ++CONFIG_POSIX_MQUEUE=y ++CONFIG_FHANDLE=y ++CONFIG_AUDIT=y ++CONFIG_AUDIT_LOGINUID_IMMUTABLE=y + CONFIG_IKCONFIG=y + CONFIG_IKCONFIG_PROC=y ++CONFIG_SYSFS_DEPRECATED=y + CONFIG_SYSFS_DEPRECATED_V2=y +-CONFIG_BLK_DEV_INITRD=y +-CONFIG_INITRAMFS_SOURCE="rootfs.cpio" +-CONFIG_INITRAMFS_COMPRESSION_GZIP=y +-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +-CONFIG_EXPERT=y + CONFIG_KALLSYMS_ALL=y +-CONFIG_KALLSYMS_EXTRA_PASS=y +-# CONFIG_HOTPLUG is not set + # CONFIG_BASE_FULL is not set +-# CONFIG_FUTEX is not set +-# CONFIG_EPOLL is not set +-# CONFIG_SIGNALFD is not set +-# CONFIG_SHMEM is not set ++CONFIG_EMBEDDED=y + CONFIG_SLAB=y + CONFIG_MODULES=y + CONFIG_MODULE_UNLOAD=y + # CONFIG_BLK_DEV_BSG is not set ++CONFIG_PARTITION_ADVANCED=y ++# CONFIG_EFI_PARTITION is not set + CONFIG_OPT_LIB_ASM=y + CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR=1 + CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR=1 +@@ -37,33 +34,53 @@ CONFIG_UNIX=y + CONFIG_INET=y + # CONFIG_INET_LRO is not set + # CONFIG_IPV6 is not set ++CONFIG_MTD=y + CONFIG_PROC_DEVICETREE=y + CONFIG_BLK_DEV_RAM=y + CONFIG_BLK_DEV_RAM_SIZE=8192 + CONFIG_NETDEVICES=y +-CONFIG_NET_ETHERNET=y + CONFIG_XILINX_EMACLITE=y ++CONFIG_XILINX_LL_TEMAC=y + # CONFIG_INPUT is not set + # CONFIG_SERIO is not set + # CONFIG_VT is not set ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y + CONFIG_SERIAL_UARTLITE=y + CONFIG_SERIAL_UARTLITE_CONSOLE=y + # CONFIG_HW_RANDOM is not set ++CONFIG_XILINX_HWICAP=y ++CONFIG_I2C=y ++CONFIG_I2C_XILINX=y ++CONFIG_SPI=y ++CONFIG_SPI_XILINX=y ++CONFIG_GPIOLIB=y ++CONFIG_GPIO_SYSFS=y ++CONFIG_GPIO_XILINX=y + # CONFIG_HWMON is not set ++CONFIG_WATCHDOG=y ++CONFIG_XILINX_WATCHDOG=y ++CONFIG_FB=y ++CONFIG_FB_XILINX=y + # CONFIG_USB_SUPPORT is not set ++CONFIG_UIO=y ++CONFIG_UIO_PDRV=y ++CONFIG_UIO_PDRV_GENIRQ=y ++CONFIG_UIO_DMEM_GENIRQ=y + CONFIG_EXT2_FS=y + # CONFIG_DNOTIFY is not set ++CONFIG_CRAMFS=y ++CONFIG_ROMFS_FS=y + CONFIG_NFS_FS=y +-CONFIG_NFS_V3=y + CONFIG_CIFS=y + CONFIG_CIFS_STATS=y + CONFIG_CIFS_STATS2=y +-CONFIG_PARTITION_ADVANCED=y +-CONFIG_DEBUG_KERNEL=y + CONFIG_DETECT_HUNG_TASK=y + CONFIG_DEBUG_SLAB=y + CONFIG_DEBUG_SPINLOCK=y + CONFIG_DEBUG_INFO=y +-# CONFIG_RCU_CPU_STALL_DETECTOR is not set + CONFIG_EARLY_PRINTK=y ++CONFIG_KEYS=y ++CONFIG_ENCRYPTED_KEYS=y ++CONFIG_KEYS_DEBUG_PROC_KEYS=y + # CONFIG_CRYPTO_ANSI_CPRNG is not set +diff --git a/arch/microblaze/configs/nommu_defconfig b/arch/microblaze/configs/nommu_defconfig +index 0249e4b..5454a6d 100644 +--- a/arch/microblaze/configs/nommu_defconfig ++++ b/arch/microblaze/configs/nommu_defconfig +@@ -1,41 +1,40 @@ + CONFIG_EXPERIMENTAL=y + CONFIG_SYSVIPC=y + CONFIG_POSIX_MQUEUE=y ++CONFIG_FHANDLE=y ++CONFIG_AUDIT=y ++CONFIG_AUDIT_LOGINUID_IMMUTABLE=y + CONFIG_BSD_PROCESS_ACCT=y + CONFIG_BSD_PROCESS_ACCT_V3=y + CONFIG_IKCONFIG=y + CONFIG_IKCONFIG_PROC=y ++CONFIG_SYSFS_DEPRECATED=y + CONFIG_SYSFS_DEPRECATED_V2=y +-CONFIG_EXPERT=y + CONFIG_KALLSYMS_ALL=y +-CONFIG_KALLSYMS_EXTRA_PASS=y +-# CONFIG_HOTPLUG is not set + # CONFIG_BASE_FULL is not set ++CONFIG_EMBEDDED=y + CONFIG_SLAB=y + CONFIG_MODULES=y + CONFIG_MODULE_UNLOAD=y + # CONFIG_BLK_DEV_BSG is not set +-# CONFIG_OPT_LIB_FUNCTION is not set ++CONFIG_PARTITION_ADVANCED=y ++# CONFIG_EFI_PARTITION is not set + CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR=1 + CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR=1 + CONFIG_XILINX_MICROBLAZE0_USE_BARREL=1 + CONFIG_XILINX_MICROBLAZE0_USE_DIV=1 + CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL=2 + CONFIG_XILINX_MICROBLAZE0_USE_FPU=2 +-CONFIG_HIGH_RES_TIMERS=y + CONFIG_HZ_100=y + CONFIG_CMDLINE_BOOL=y +-CONFIG_BINFMT_FLAT=y ++CONFIG_CMDLINE_FORCE=y + CONFIG_NET=y + CONFIG_PACKET=y + CONFIG_UNIX=y + CONFIG_INET=y + # CONFIG_INET_LRO is not set + # CONFIG_IPV6 is not set +-# CONFIG_PREVENT_FIRMWARE_BUILD is not set + CONFIG_MTD=y +-CONFIG_MTD_CONCAT=y +-CONFIG_MTD_PARTITIONS=y + CONFIG_MTD_CMDLINE_PARTS=y + CONFIG_MTD_CHAR=y + CONFIG_MTD_BLOCK=y +@@ -45,41 +44,55 @@ CONFIG_MTD_CFI_AMDSTD=y + CONFIG_MTD_RAM=y + CONFIG_MTD_UCLINUX=y + CONFIG_PROC_DEVICETREE=y +-CONFIG_BLK_DEV_NBD=y + CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_SIZE=8192 + CONFIG_NETDEVICES=y +-CONFIG_NET_ETHERNET=y ++CONFIG_XILINX_EMACLITE=y ++CONFIG_XILINX_LL_TEMAC=y + # CONFIG_INPUT is not set + # CONFIG_SERIO is not set + # CONFIG_VT is not set ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y + CONFIG_SERIAL_UARTLITE=y + CONFIG_SERIAL_UARTLITE_CONSOLE=y +-CONFIG_HW_RANDOM=y ++# CONFIG_HW_RANDOM is not set ++CONFIG_XILINX_HWICAP=y ++CONFIG_I2C=y ++CONFIG_I2C_XILINX=y ++CONFIG_SPI=y ++CONFIG_SPI_XILINX=y ++CONFIG_GPIOLIB=y ++CONFIG_GPIO_SYSFS=y ++CONFIG_GPIO_XILINX=y + # CONFIG_HWMON is not set +-CONFIG_VIDEO_OUTPUT_CONTROL=y ++CONFIG_WATCHDOG=y ++CONFIG_XILINX_WATCHDOG=y ++CONFIG_FB=y ++CONFIG_FB_XILINX=y ++# CONFIG_USB_SUPPORT is not set ++CONFIG_UIO=y ++CONFIG_UIO_PDRV=y ++CONFIG_UIO_PDRV_GENIRQ=y ++CONFIG_UIO_DMEM_GENIRQ=y + CONFIG_EXT2_FS=y + # CONFIG_DNOTIFY is not set + CONFIG_CRAMFS=y + CONFIG_ROMFS_FS=y + CONFIG_NFS_FS=y +-CONFIG_NFS_V3=y + CONFIG_NFS_V3_ACL=y +-CONFIG_UNUSED_SYMBOLS=y +-CONFIG_DEBUG_FS=y +-CONFIG_DEBUG_KERNEL=y +-CONFIG_DEBUG_SHIRQ=y ++CONFIG_NLS=y + CONFIG_DETECT_HUNG_TASK=y +-CONFIG_SCHEDSTATS=y +-CONFIG_TIMER_STATS=y +-CONFIG_DEBUG_OBJECTS=y +-CONFIG_DEBUG_OBJECTS_SELFTEST=y +-CONFIG_DEBUG_OBJECTS_FREE=y +-CONFIG_DEBUG_OBJECTS_TIMERS=y ++CONFIG_DEBUG_SLAB=y ++CONFIG_DEBUG_SPINLOCK=y + CONFIG_DEBUG_INFO=y +-CONFIG_DEBUG_LIST=y +-CONFIG_DEBUG_SG=y +-# CONFIG_RCU_CPU_STALL_DETECTOR is not set +-CONFIG_SYSCTL_SYSCALL_CHECK=y + CONFIG_EARLY_PRINTK=y ++CONFIG_KEYS=y ++CONFIG_ENCRYPTED_KEYS=y ++CONFIG_KEYS_DEBUG_PROC_KEYS=y ++CONFIG_CRYPTO_ECB=y ++CONFIG_CRYPTO_MD4=y ++CONFIG_CRYPTO_MD5=y ++CONFIG_CRYPTO_ARC4=y ++CONFIG_CRYPTO_DES=y + # CONFIG_CRYPTO_ANSI_CPRNG is not set +-# CONFIG_CRC32 is not set +diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig +index ce30e2f..7d36f6e 100644 +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -24,6 +24,7 @@ config MIPS + select HAVE_GENERIC_HARDIRQS + select GENERIC_IRQ_PROBE + select GENERIC_IRQ_SHOW ++ select GENERIC_PCI_IOMAP + select HAVE_ARCH_JUMP_LABEL + select IRQ_FORCED_THREADING + select HAVE_MEMBLOCK +@@ -2356,7 +2357,6 @@ config PCI + bool "Support for PCI controller" + depends on HW_HAS_PCI + select PCI_DOMAINS +- select GENERIC_PCI_IOMAP + select NO_GENERIC_PCI_IOPORT_MAP + help + Find out whether you have a PCI motherboard. PCI is the name of a +diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h +index a58f229..f7b3e1c 100644 +--- a/arch/mips/include/asm/io.h ++++ b/arch/mips/include/asm/io.h +@@ -168,6 +168,11 @@ static inline void * isa_bus_to_virt(unsigned long address) + extern void __iomem * __ioremap(phys_t offset, phys_t size, unsigned long flags); + extern void __iounmap(const volatile void __iomem *addr); + ++#ifndef CONFIG_PCI ++struct pci_dev; ++static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {} ++#endif ++ + static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, + unsigned long flags) + { +diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h +index da9bd7d..0913b4f 100644 +--- a/arch/mips/include/asm/page.h ++++ b/arch/mips/include/asm/page.h +@@ -175,14 +175,15 @@ typedef struct { unsigned long pgprot; } pgprot_t; + + #ifdef CONFIG_FLATMEM + +-#define pfn_valid(pfn) \ +-({ \ +- unsigned long __pfn = (pfn); \ +- /* avoid include hell */ \ +- extern unsigned long min_low_pfn; \ +- \ +- __pfn >= min_low_pfn && __pfn < max_mapnr; \ +-}) ++#ifndef __ASSEMBLY__ ++static inline int pfn_valid(unsigned long pfn) ++{ ++ /* avoid include hell */ ++ extern unsigned long max_mapnr; ++ ++ return pfn >= ARCH_PFN_OFFSET && pfn < max_mapnr; ++} ++#endif + + #elif defined(CONFIG_SPARSEMEM) + +diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c +index 6130719..4ec32a6 100644 +--- a/arch/powerpc/mm/numa.c ++++ b/arch/powerpc/mm/numa.c +@@ -639,7 +639,7 @@ static void __init parse_drconf_memory(struct device_node *memory) + unsigned int n, rc, ranges, is_kexec_kdump = 0; + unsigned long lmb_size, base, size, sz; + int nid; +- struct assoc_arrays aa; ++ struct assoc_arrays aa = { .arrays = NULL }; + + n = of_get_drconf_memory(memory, &dm); + if (!n) +diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile +index a3fc437..4961516 100644 +--- a/arch/sparc/lib/Makefile ++++ b/arch/sparc/lib/Makefile +@@ -40,7 +40,7 @@ lib-$(CONFIG_SPARC64) += copy_in_user.o user_fixup.o memmove.o + lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o + + obj-y += iomap.o +-obj-$(CONFIG_SPARC32) += atomic32.o ++obj-$(CONFIG_SPARC32) += atomic32.o ucmpdi2.o + obj-y += ksyms.o + obj-$(CONFIG_SPARC64) += PeeCeeI.o + obj-y += usercopy.o +diff --git a/arch/sparc/lib/ucmpdi2.c b/arch/sparc/lib/ucmpdi2.c +new file mode 100644 +index 0000000..1e06ed5 +--- /dev/null ++++ b/arch/sparc/lib/ucmpdi2.c +@@ -0,0 +1,19 @@ ++#include ++#include "libgcc.h" ++ ++word_type __ucmpdi2(unsigned long long a, unsigned long long b) ++{ ++ const DWunion au = {.ll = a}; ++ const DWunion bu = {.ll = b}; ++ ++ if ((unsigned int) au.s.high < (unsigned int) bu.s.high) ++ return 0; ++ else if ((unsigned int) au.s.high > (unsigned int) bu.s.high) ++ return 2; ++ if ((unsigned int) au.s.low < (unsigned int) bu.s.low) ++ return 0; ++ else if ((unsigned int) au.s.low > (unsigned int) bu.s.low) ++ return 2; ++ return 1; ++} ++EXPORT_SYMBOL(__ucmpdi2); +diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile +index 2d2728b..491bd9a 100644 +--- a/arch/xtensa/kernel/Makefile ++++ b/arch/xtensa/kernel/Makefile +@@ -24,6 +24,7 @@ obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o + # Replicate rules in scripts/Makefile.build + + sed-y = -e 's/\*(\(\.[a-z]*it\|\.ref\|\)\.text)/*(\1.literal \1.text)/g' \ ++ -e 's/\.text\.unlikely/.literal.unlikely .text.unlikely/g' \ + -e 's/\*(\(\.text\.[a-z]*\))/*(\1.literal \1)/g' + + quiet_cmd__cpp_lds_S = LDS $@ +diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S +index 88ecea3..ee2e208 100644 +--- a/arch/xtensa/kernel/vmlinux.lds.S ++++ b/arch/xtensa/kernel/vmlinux.lds.S +@@ -83,7 +83,6 @@ SECTIONS + + _text = .; + _stext = .; +- _ftext = .; + + .text : + { +@@ -112,7 +111,7 @@ SECTIONS + EXCEPTION_TABLE(16) + /* Data section */ + +- _fdata = .; ++ _sdata = .; + RW_DATA_SECTION(XCHAL_ICACHE_LINESIZE, PAGE_SIZE, THREAD_SIZE) + _edata = .; + +diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c +index ba150e5..c82af58 100644 +--- a/arch/xtensa/mm/init.c ++++ b/arch/xtensa/mm/init.c +@@ -29,7 +29,7 @@ + + /* References to section boundaries */ + +-extern char _ftext, _etext, _fdata, _edata, _rodata_end; ++extern char _stext, _etext, _sdata, _edata, _rodata_end; + extern char __init_begin, __init_end; + + /* +@@ -197,8 +197,8 @@ void __init mem_init(void) + reservedpages++; + } + +- codesize = (unsigned long) &_etext - (unsigned long) &_ftext; +- datasize = (unsigned long) &_edata - (unsigned long) &_fdata; ++ codesize = (unsigned long) &_etext - (unsigned long) &_stext; ++ datasize = (unsigned long) &_edata - (unsigned long) &_sdata; + initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; + + printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, " +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index ab4d990..dc7c5f6 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -408,13 +408,7 @@ static void intel_lvds_prepare(struct drm_encoder *encoder) + { + struct intel_lvds *intel_lvds = to_intel_lvds(encoder); + +- /* +- * Prior to Ironlake, we must disable the pipe if we want to adjust +- * the panel fitter. However at all other times we can just reset +- * the registers regardless. +- */ +- if (!HAS_PCH_SPLIT(encoder->dev) && intel_lvds->pfit_dirty) +- intel_lvds_disable(intel_lvds); ++ intel_lvds_disable(intel_lvds); + } + + static void intel_lvds_commit(struct drm_encoder *encoder) +diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c +index 3899989..259b9f4 100644 +--- a/drivers/hid/hid-microsoft.c ++++ b/drivers/hid/hid-microsoft.c +@@ -47,9 +47,9 @@ static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc, + rdesc[559] = 0x45; + } + /* the same as above (s/usage/physical/) */ +- if ((quirks & MS_RDESC_3K) && *rsize == 106 && +- !memcmp((char []){ 0x19, 0x00, 0x29, 0xff }, +- &rdesc[94], 4)) { ++ if ((quirks & MS_RDESC_3K) && *rsize == 106 && rdesc[94] == 0x19 && ++ rdesc[95] == 0x00 && rdesc[96] == 0x29 && ++ rdesc[97] == 0xff) { + rdesc[94] = 0x35; + rdesc[96] = 0x45; + } +diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c +index b424a20..ce5f044 100644 +--- a/drivers/md/raid1.c ++++ b/drivers/md/raid1.c +@@ -812,17 +812,17 @@ static void allow_barrier(struct r1conf *conf) + wake_up(&conf->wait_barrier); + } + +-static void freeze_array(struct r1conf *conf) ++static void freeze_array(struct r1conf *conf, int extra) + { + /* stop syncio and normal IO and wait for everything to + * go quite. + * We increment barrier and nr_waiting, and then +- * wait until nr_pending match nr_queued+1 ++ * wait until nr_pending match nr_queued+extra + * This is called in the context of one normal IO request + * that has failed. Thus any sync request that might be pending + * will be blocked by nr_pending, and we need to wait for + * pending IO requests to complete or be queued for re-try. +- * Thus the number queued (nr_queued) plus this request (1) ++ * Thus the number queued (nr_queued) plus this request (extra) + * must match the number of pending IOs (nr_pending) before + * we continue. + */ +@@ -830,7 +830,7 @@ static void freeze_array(struct r1conf *conf) + conf->barrier++; + conf->nr_waiting++; + wait_event_lock_irq(conf->wait_barrier, +- conf->nr_pending == conf->nr_queued+1, ++ conf->nr_pending == conf->nr_queued+extra, + conf->resync_lock, + flush_pending_writes(conf)); + spin_unlock_irq(&conf->resync_lock); +@@ -1432,8 +1432,8 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev) + * we wait for all outstanding requests to complete. + */ + synchronize_sched(); +- raise_barrier(conf); +- lower_barrier(conf); ++ freeze_array(conf, 0); ++ unfreeze_array(conf); + clear_bit(Unmerged, &rdev->flags); + } + md_integrity_add_rdev(rdev, mddev); +@@ -1481,11 +1481,11 @@ static int raid1_remove_disk(struct mddev *mddev, struct md_rdev *rdev) + */ + struct md_rdev *repl = + conf->mirrors[conf->raid_disks + number].rdev; +- raise_barrier(conf); ++ freeze_array(conf, 0); + clear_bit(Replacement, &repl->flags); + p->rdev = repl; + conf->mirrors[conf->raid_disks + number].rdev = NULL; +- lower_barrier(conf); ++ unfreeze_array(conf); + clear_bit(WantReplacement, &rdev->flags); + } else + clear_bit(WantReplacement, &rdev->flags); +@@ -2100,7 +2100,7 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio) + * frozen + */ + if (mddev->ro == 0) { +- freeze_array(conf); ++ freeze_array(conf, 1); + fix_read_error(conf, r1_bio->read_disk, + r1_bio->sector, r1_bio->sectors); + unfreeze_array(conf); +@@ -2855,7 +2855,7 @@ static int raid1_reshape(struct mddev *mddev) + return -ENOMEM; + } + +- raise_barrier(conf); ++ freeze_array(conf, 0); + + /* ok, everything is stopped */ + oldpool = conf->r1bio_pool; +@@ -2887,7 +2887,7 @@ static int raid1_reshape(struct mddev *mddev) + mddev->delta_disks = 0; + + conf->last_used = 0; /* just make sure it is in-range */ +- lower_barrier(conf); ++ unfreeze_array(conf); + + set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); + md_wakeup_thread(mddev->thread); +diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c +index 54ba531..f7febd8 100644 +--- a/drivers/md/raid10.c ++++ b/drivers/md/raid10.c +@@ -952,17 +952,17 @@ static void allow_barrier(struct r10conf *conf) + wake_up(&conf->wait_barrier); + } + +-static void freeze_array(struct r10conf *conf) ++static void freeze_array(struct r10conf *conf, int extra) + { + /* stop syncio and normal IO and wait for everything to + * go quiet. + * We increment barrier and nr_waiting, and then +- * wait until nr_pending match nr_queued+1 ++ * wait until nr_pending match nr_queued+extra + * This is called in the context of one normal IO request + * that has failed. Thus any sync request that might be pending + * will be blocked by nr_pending, and we need to wait for + * pending IO requests to complete or be queued for re-try. +- * Thus the number queued (nr_queued) plus this request (1) ++ * Thus the number queued (nr_queued) plus this request (extra) + * must match the number of pending IOs (nr_pending) before + * we continue. + */ +@@ -970,7 +970,7 @@ static void freeze_array(struct r10conf *conf) + conf->barrier++; + conf->nr_waiting++; + wait_event_lock_irq(conf->wait_barrier, +- conf->nr_pending == conf->nr_queued+1, ++ conf->nr_pending == conf->nr_queued+extra, + conf->resync_lock, + flush_pending_writes(conf)); + +@@ -1619,8 +1619,8 @@ static int raid10_add_disk(struct mddev *mddev, struct md_rdev *rdev) + * we wait for all outstanding requests to complete. + */ + synchronize_sched(); +- raise_barrier(conf, 0); +- lower_barrier(conf); ++ freeze_array(conf, 0); ++ unfreeze_array(conf); + clear_bit(Unmerged, &rdev->flags); + } + md_integrity_add_rdev(rdev, mddev); +@@ -2410,7 +2410,7 @@ static void handle_read_error(struct mddev *mddev, struct r10bio *r10_bio) + r10_bio->devs[slot].bio = NULL; + + if (mddev->ro == 0) { +- freeze_array(conf); ++ freeze_array(conf, 1); + fix_read_error(conf, mddev, r10_bio); + unfreeze_array(conf); + } else +diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c +index 25723d8..925ab8e 100644 +--- a/drivers/net/can/usb/peak_usb/pcan_usb.c ++++ b/drivers/net/can/usb/peak_usb/pcan_usb.c +@@ -649,7 +649,7 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len) + if ((mc->ptr + rec_len) > mc->end) + goto decode_failed; + +- memcpy(cf->data, mc->ptr, rec_len); ++ memcpy(cf->data, mc->ptr, cf->can_dlc); + mc->ptr += rec_len; + } + +diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c +index 9aa4807..409ed06 100644 +--- a/drivers/net/wireless/iwlegacy/4965-mac.c ++++ b/drivers/net/wireless/iwlegacy/4965-mac.c +@@ -4411,12 +4411,12 @@ il4965_irq_tasklet(struct il_priv *il) + * is killed. Hence update the killswitch state here. The + * rfkill handler will care about restarting if needed. + */ +- if (!test_bit(S_ALIVE, &il->status)) { +- if (hw_rf_kill) +- set_bit(S_RFKILL, &il->status); +- else +- clear_bit(S_RFKILL, &il->status); ++ if (hw_rf_kill) { ++ set_bit(S_RFKILL, &il->status); ++ } else { ++ clear_bit(S_RFKILL, &il->status); + wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rf_kill); ++ il_force_reset(il, true); + } + + handled |= CSR_INT_BIT_RF_KILL; +@@ -5285,6 +5285,9 @@ il4965_alive_start(struct il_priv *il) + + il->active_rate = RATES_MASK; + ++ il_power_update_mode(il, true); ++ D_INFO("Updated power mode\n"); ++ + if (il_is_associated(il)) { + struct il_rxon_cmd *active_rxon = + (struct il_rxon_cmd *)&il->active; +@@ -5315,9 +5318,6 @@ il4965_alive_start(struct il_priv *il) + D_INFO("ALIVE processing complete.\n"); + wake_up(&il->wait_command_queue); + +- il_power_update_mode(il, true); +- D_INFO("Updated power mode\n"); +- + return; + + restart: +diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c +index 2ab6b96..ae4befa 100644 +--- a/drivers/net/wireless/iwlegacy/common.c ++++ b/drivers/net/wireless/iwlegacy/common.c +@@ -4659,6 +4659,7 @@ il_force_reset(struct il_priv *il, bool external) + + return 0; + } ++EXPORT_SYMBOL(il_force_reset); + + int + il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index f88ad63..8659cd9 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -100,6 +100,12 @@ static const struct usb_device_id usb_quirk_list[] = { + { USB_DEVICE(0x04d8, 0x000c), .driver_info = + USB_QUIRK_CONFIG_INTF_STRINGS }, + ++ /* CarrolTouch 4000U */ ++ { USB_DEVICE(0x04e7, 0x0009), .driver_info = USB_QUIRK_RESET_RESUME }, ++ ++ /* CarrolTouch 4500U */ ++ { USB_DEVICE(0x04e7, 0x0030), .driver_info = USB_QUIRK_RESET_RESUME }, ++ + /* Samsung Android phone modem - ID conflict with SPH-I500 */ + { USB_DEVICE(0x04e8, 0x6601), .driver_info = + USB_QUIRK_CONFIG_INTF_STRINGS }, +diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c +index 77d974d..cdde45d 100644 +--- a/drivers/usb/serial/mos7720.c ++++ b/drivers/usb/serial/mos7720.c +@@ -97,6 +97,7 @@ struct urbtracker { + struct list_head urblist_entry; + struct kref ref_count; + struct urb *urb; ++ struct usb_ctrlrequest *setup; + }; + + enum mos7715_pp_modes { +@@ -279,6 +280,7 @@ static void destroy_urbtracker(struct kref *kref) + struct mos7715_parport *mos_parport = urbtrack->mos_parport; + dbg("%s called", __func__); + usb_free_urb(urbtrack->urb); ++ kfree(urbtrack->setup); + kfree(urbtrack); + kref_put(&mos_parport->ref_count, destroy_mos_parport); + } +@@ -363,7 +365,6 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport, + struct urbtracker *urbtrack; + int ret_val; + unsigned long flags; +- struct usb_ctrlrequest setup; + struct usb_serial *serial = mos_parport->serial; + struct usb_device *usbdev = serial->dev; + dbg("%s called", __func__); +@@ -382,14 +383,20 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport, + kfree(urbtrack); + return -ENOMEM; + } +- setup.bRequestType = (__u8)0x40; +- setup.bRequest = (__u8)0x0e; +- setup.wValue = get_reg_value(reg, dummy); +- setup.wIndex = get_reg_index(reg); +- setup.wLength = 0; ++ urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_KERNEL); ++ if (!urbtrack->setup) { ++ usb_free_urb(urbtrack->urb); ++ kfree(urbtrack); ++ return -ENOMEM; ++ } ++ urbtrack->setup->bRequestType = (__u8)0x40; ++ urbtrack->setup->bRequest = (__u8)0x0e; ++ urbtrack->setup->wValue = get_reg_value(reg, dummy); ++ urbtrack->setup->wIndex = get_reg_index(reg); ++ urbtrack->setup->wLength = 0; + usb_fill_control_urb(urbtrack->urb, usbdev, + usb_sndctrlpipe(usbdev, 0), +- (unsigned char *)&setup, ++ (unsigned char *)urbtrack->setup, + NULL, 0, async_complete, urbtrack); + kref_init(&urbtrack->ref_count); + INIT_LIST_HEAD(&urbtrack->urblist_entry); +diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c +index aca1790..d0b8f98 100644 +--- a/fs/ext4/ext4_jbd2.c ++++ b/fs/ext4/ext4_jbd2.c +@@ -109,10 +109,10 @@ int __ext4_handle_dirty_metadata(const char *where, unsigned int line, + + if (ext4_handle_valid(handle)) { + err = jbd2_journal_dirty_metadata(handle, bh); +- if (err) { +- /* Errors can only happen if there is a bug */ +- handle->h_err = err; +- __ext4_journal_stop(where, line, handle); ++ /* Errors can only happen if there is a bug */ ++ if (WARN_ON_ONCE(err)) { ++ ext4_journal_abort_handle(where, line, __func__, bh, ++ handle, err); + } + } else { + if (inode) +diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c +index 7faaf2a..8df7fd2 100644 +--- a/fs/proc/task_mmu.c ++++ b/fs/proc/task_mmu.c +@@ -679,14 +679,14 @@ typedef struct { + } pagemap_entry_t; + + struct pagemapread { +- int pos, len; ++ int pos, len; /* units: PM_ENTRY_BYTES, not bytes */ + pagemap_entry_t *buffer; + }; + + #define PAGEMAP_WALK_SIZE (PMD_SIZE) + #define PAGEMAP_WALK_MASK (PMD_MASK) + +-#define PM_ENTRY_BYTES sizeof(u64) ++#define PM_ENTRY_BYTES sizeof(pagemap_entry_t) + #define PM_STATUS_BITS 3 + #define PM_STATUS_OFFSET (64 - PM_STATUS_BITS) + #define PM_STATUS_MASK (((1LL << PM_STATUS_BITS) - 1) << PM_STATUS_OFFSET) +@@ -913,8 +913,8 @@ static ssize_t pagemap_read(struct file *file, char __user *buf, + if (!count) + goto out_task; + +- pm.len = PM_ENTRY_BYTES * (PAGEMAP_WALK_SIZE >> PAGE_SHIFT); +- pm.buffer = kmalloc(pm.len, GFP_TEMPORARY); ++ pm.len = (PAGEMAP_WALK_SIZE >> PAGE_SHIFT); ++ pm.buffer = kmalloc(pm.len * PM_ENTRY_BYTES, GFP_TEMPORARY); + ret = -ENOMEM; + if (!pm.buffer) + goto out_task; +diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h +index 2c36a71..6baa73d 100644 +--- a/include/linux/hugetlb.h ++++ b/include/linux/hugetlb.h +@@ -293,6 +293,17 @@ static inline unsigned hstate_index_to_shift(unsigned index) + return hstates[index].order + PAGE_SHIFT; + } + ++pgoff_t __basepage_index(struct page *page); ++ ++/* Return page->index in PAGE_SIZE units */ ++static inline pgoff_t basepage_index(struct page *page) ++{ ++ if (!PageCompound(page)) ++ return page->index; ++ ++ return __basepage_index(page); ++} ++ + #else /* CONFIG_HUGETLB_PAGE */ + struct hstate {}; + #define alloc_huge_page_node(h, nid) NULL +@@ -311,6 +322,11 @@ static inline unsigned int pages_per_huge_page(struct hstate *h) + return 1; + } + #define hstate_index_to_shift(index) 0 ++ ++static inline pgoff_t basepage_index(struct page *page) ++{ ++ return page->index; ++} + #endif + + #endif /* _LINUX_HUGETLB_H */ +diff --git a/kernel/futex.c b/kernel/futex.c +index 8879430..f0ee318 100644 +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -60,7 +60,8 @@ + #include + #include + #include ++#include + #include + + #include + +@@ -363,7 +364,7 @@ again: + } else { + key->both.offset |= FUT_OFF_INODE; /* inode-based key */ + key->shared.inode = page_head->mapping->host; +- key->shared.pgoff = page_head->index; ++ key->shared.pgoff = basepage_index(page); + } + + get_futex_key_refs(key); +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index a692439..af20b77 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -679,6 +679,23 @@ int PageHuge(struct page *page) + } + EXPORT_SYMBOL_GPL(PageHuge); + ++pgoff_t __basepage_index(struct page *page) ++{ ++ struct page *page_head = compound_head(page); ++ pgoff_t index = page_index(page_head); ++ unsigned long compound_idx; ++ ++ if (!PageHuge(page_head)) ++ return page_index(page); ++ ++ if (compound_order(page_head) >= MAX_ORDER) ++ compound_idx = page_to_pfn(page) - page_to_pfn(page_head); ++ else ++ compound_idx = page - page_head; ++ ++ return (index << compound_order(page_head)) + compound_idx; ++} ++ + static struct page *alloc_fresh_huge_page_node(struct hstate *h, int nid) + { + struct page *page; +diff --git a/mm/nommu.c b/mm/nommu.c +index b0956e3..d3afb47 100644 +--- a/mm/nommu.c ++++ b/mm/nommu.c +@@ -1856,6 +1856,16 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, + } + EXPORT_SYMBOL(remap_pfn_range); + ++int vm_iomap_memory(struct vm_area_struct *vma, phys_addr_t start, unsigned long len) ++{ ++ unsigned long pfn = start >> PAGE_SHIFT; ++ unsigned long vm_len = vma->vm_end - vma->vm_start; ++ ++ pfn += vma->vm_pgoff; ++ return io_remap_pfn_range(vma, vma->vm_start, pfn, vm_len, vma->vm_page_prot); ++} ++EXPORT_SYMBOL(vm_iomap_memory); ++ + int remap_vmalloc_range(struct vm_area_struct *vma, void *addr, + unsigned long pgoff) + { +diff --git a/net/key/af_key.c b/net/key/af_key.c +index 60109f4..2f3ce93 100644 +--- a/net/key/af_key.c ++++ b/net/key/af_key.c +@@ -2687,6 +2687,7 @@ static int key_notify_policy_flush(const struct km_event *c) + hdr->sadb_msg_pid = c->pid; + hdr->sadb_msg_version = PF_KEY_V2; + hdr->sadb_msg_errno = (uint8_t) 0; ++ hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC; + hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); + hdr->sadb_msg_reserved = 0; + pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); +diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig +index 5849b12..1a96402 100644 +--- a/sound/oss/Kconfig ++++ b/sound/oss/Kconfig +@@ -250,6 +250,7 @@ config MSND_FIFOSIZE + menuconfig SOUND_OSS + tristate "OSS sound modules" + depends on ISA_DMA_API && VIRT_TO_BUS ++ depends on !GENERIC_ISA_DMA_SUPPORT_BROKEN + help + OSS is the Open Sound System suite of sound card drivers. They make + sound programming easier since they provide a common API. Say Y or diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.59-60.patch b/patch/kernel/sun8i-default/0001-patch-3.4.59-60.patch new file mode 100644 index 000000000..8d4d89bd6 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.59-60.patch @@ -0,0 +1,579 @@ +diff --git a/Makefile b/Makefile +index efa1453..0027fbe 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 59 ++SUBLEVEL = 60 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c +index 017d48a..f8b0260 100644 +--- a/arch/x86/xen/setup.c ++++ b/arch/x86/xen/setup.c +@@ -213,6 +213,17 @@ static void xen_align_and_add_e820_region(u64 start, u64 size, int type) + e820_add_region(start, end - start, type); + } + ++void xen_ignore_unusable(struct e820entry *list, size_t map_size) ++{ ++ struct e820entry *entry; ++ unsigned int i; ++ ++ for (i = 0, entry = list; i < map_size; i++, entry++) { ++ if (entry->type == E820_UNUSABLE) ++ entry->type = E820_RAM; ++ } ++} ++ + /** + * machine_specific_memory_setup - Hook for machine specific memory setup. + **/ +@@ -251,6 +262,17 @@ char * __init xen_memory_setup(void) + } + BUG_ON(rc); + ++ /* ++ * Xen won't allow a 1:1 mapping to be created to UNUSABLE ++ * regions, so if we're using the machine memory map leave the ++ * region as RAM as it is in the pseudo-physical map. ++ * ++ * UNUSABLE regions in domUs are not handled and will need ++ * a patch in the future. ++ */ ++ if (xen_initial_domain()) ++ xen_ignore_unusable(map, memmap.nr_entries); ++ + /* Make sure the Xen-supplied memory map is well-ordered. */ + sanitize_e820_map(map, memmap.nr_entries, &memmap.nr_entries); + +diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c +index f63a588..f5c35be 100644 +--- a/drivers/ata/libata-pmp.c ++++ b/drivers/ata/libata-pmp.c +@@ -289,24 +289,24 @@ static int sata_pmp_configure(struct ata_device *dev, int print_info) + + /* Disable sending Early R_OK. + * With "cached read" HDD testing and multiple ports busy on a SATA +- * host controller, 3726 PMP will very rarely drop a deferred ++ * host controller, 3x26 PMP will very rarely drop a deferred + * R_OK that was intended for the host. Symptom will be all + * 5 drives under test will timeout, get reset, and recover. + */ +- if (vendor == 0x1095 && devid == 0x3726) { ++ if (vendor == 0x1095 && (devid == 0x3726 || devid == 0x3826)) { + u32 reg; + + err_mask = sata_pmp_read(&ap->link, PMP_GSCR_SII_POL, ®); + if (err_mask) { + rc = -EIO; +- reason = "failed to read Sil3726 Private Register"; ++ reason = "failed to read Sil3x26 Private Register"; + goto fail; + } + reg &= ~0x1; + err_mask = sata_pmp_write(&ap->link, PMP_GSCR_SII_POL, reg); + if (err_mask) { + rc = -EIO; +- reason = "failed to write Sil3726 Private Register"; ++ reason = "failed to write Sil3x26 Private Register"; + goto fail; + } + } +@@ -383,8 +383,8 @@ static void sata_pmp_quirks(struct ata_port *ap) + u16 devid = sata_pmp_gscr_devid(gscr); + struct ata_link *link; + +- if (vendor == 0x1095 && devid == 0x3726) { +- /* sil3726 quirks */ ++ if (vendor == 0x1095 && (devid == 0x3726 || devid == 0x3826)) { ++ /* sil3x26 quirks */ + ata_for_each_link(link, ap, EDGE) { + /* link reports offline after LPM */ + link->flags |= ATA_LFLAG_NO_LPM; +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index dde62bf..d031932 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -502,6 +502,8 @@ + will not assert AGPBUSY# and will only + be delivered when out of C3. */ + #define INSTPM_FORCE_ORDERING (1<<7) /* GEN6+ */ ++#define INSTPM_TLB_INVALIDATE (1<<9) ++#define INSTPM_SYNC_FLUSH (1<<5) + #define ACTHD 0x020c8 + #define FW_BLC 0x020d8 + #define FW_BLC2 0x020dc +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index c17325c..99a9df8 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -767,6 +767,18 @@ void intel_ring_setup_status_page(struct intel_ring_buffer *ring) + + I915_WRITE(mmio, (u32)ring->status_page.gfx_addr); + POSTING_READ(mmio); ++ ++ /* Flush the TLB for this page */ ++ if (INTEL_INFO(dev)->gen >= 6) { ++ u32 reg = RING_INSTPM(ring->mmio_base); ++ I915_WRITE(reg, ++ _MASKED_BIT_ENABLE(INSTPM_TLB_INVALIDATE | ++ INSTPM_SYNC_FLUSH)); ++ if (wait_for((I915_READ(reg) & INSTPM_SYNC_FLUSH) == 0, ++ 1000)) ++ DRM_ERROR("%s: wait for SyncFlush to complete for TLB invalidation timed out\n", ++ ring->name); ++ } + } + + static int +diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c +index 18054d9..dbec2ff 100644 +--- a/drivers/net/wireless/hostap/hostap_ioctl.c ++++ b/drivers/net/wireless/hostap/hostap_ioctl.c +@@ -522,9 +522,9 @@ static int prism2_ioctl_giwaplist(struct net_device *dev, + + data->length = prism2_ap_get_sta_qual(local, addr, qual, IW_MAX_AP, 1); + +- memcpy(extra, &addr, sizeof(struct sockaddr) * data->length); ++ memcpy(extra, addr, sizeof(struct sockaddr) * data->length); + data->flags = 1; /* has quality information */ +- memcpy(extra + sizeof(struct sockaddr) * data->length, &qual, ++ memcpy(extra + sizeof(struct sockaddr) * data->length, qual, + sizeof(struct iw_quality) * data->length); + + kfree(addr); +diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c +index a66b93b..1662fcc 100644 +--- a/drivers/net/wireless/zd1201.c ++++ b/drivers/net/wireless/zd1201.c +@@ -98,10 +98,12 @@ static int zd1201_fw_upload(struct usb_device *dev, int apfw) + goto exit; + + err = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 0x4, +- USB_DIR_IN | 0x40, 0,0, &ret, sizeof(ret), ZD1201_FW_TIMEOUT); ++ USB_DIR_IN | 0x40, 0, 0, buf, sizeof(ret), ZD1201_FW_TIMEOUT); + if (err < 0) + goto exit; + ++ memcpy(&ret, buf, sizeof(ret)); ++ + if (ret & 0x80) { + err = -EIO; + goto exit; +diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c +index 91a375f..17fad3b 100644 +--- a/drivers/of/fdt.c ++++ b/drivers/of/fdt.c +@@ -390,6 +390,8 @@ static void __unflatten_device_tree(struct boot_param_header *blob, + mem = (unsigned long) + dt_alloc(size + 4, __alignof__(struct device_node)); + ++ memset((void *)mem, 0, size); ++ + ((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef); + + pr_debug(" unflattening %lx...\n", mem); +diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c +index e1b4f80..5c87270 100644 +--- a/drivers/s390/scsi/zfcp_erp.c ++++ b/drivers/s390/scsi/zfcp_erp.c +@@ -102,10 +102,13 @@ static void zfcp_erp_action_dismiss_port(struct zfcp_port *port) + + if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_INUSE) + zfcp_erp_action_dismiss(&port->erp_action); +- else +- shost_for_each_device(sdev, port->adapter->scsi_host) ++ else { ++ spin_lock(port->adapter->scsi_host->host_lock); ++ __shost_for_each_device(sdev, port->adapter->scsi_host) + if (sdev_to_zfcp(sdev)->port == port) + zfcp_erp_action_dismiss_lun(sdev); ++ spin_unlock(port->adapter->scsi_host->host_lock); ++ } + } + + static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter) +@@ -592,9 +595,11 @@ static void _zfcp_erp_lun_reopen_all(struct zfcp_port *port, int clear, + { + struct scsi_device *sdev; + +- shost_for_each_device(sdev, port->adapter->scsi_host) ++ spin_lock(port->adapter->scsi_host->host_lock); ++ __shost_for_each_device(sdev, port->adapter->scsi_host) + if (sdev_to_zfcp(sdev)->port == port) + _zfcp_erp_lun_reopen(sdev, clear, id, 0); ++ spin_unlock(port->adapter->scsi_host->host_lock); + } + + static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act) +@@ -1435,8 +1440,10 @@ void zfcp_erp_set_adapter_status(struct zfcp_adapter *adapter, u32 mask) + atomic_set_mask(common_mask, &port->status); + read_unlock_irqrestore(&adapter->port_list_lock, flags); + +- shost_for_each_device(sdev, adapter->scsi_host) ++ spin_lock_irqsave(adapter->scsi_host->host_lock, flags); ++ __shost_for_each_device(sdev, adapter->scsi_host) + atomic_set_mask(common_mask, &sdev_to_zfcp(sdev)->status); ++ spin_unlock_irqrestore(adapter->scsi_host->host_lock, flags); + } + + /** +@@ -1470,11 +1477,13 @@ void zfcp_erp_clear_adapter_status(struct zfcp_adapter *adapter, u32 mask) + } + read_unlock_irqrestore(&adapter->port_list_lock, flags); + +- shost_for_each_device(sdev, adapter->scsi_host) { ++ spin_lock_irqsave(adapter->scsi_host->host_lock, flags); ++ __shost_for_each_device(sdev, adapter->scsi_host) { + atomic_clear_mask(common_mask, &sdev_to_zfcp(sdev)->status); + if (clear_counter) + atomic_set(&sdev_to_zfcp(sdev)->erp_counter, 0); + } ++ spin_unlock_irqrestore(adapter->scsi_host->host_lock, flags); + } + + /** +@@ -1488,16 +1497,19 @@ void zfcp_erp_set_port_status(struct zfcp_port *port, u32 mask) + { + struct scsi_device *sdev; + u32 common_mask = mask & ZFCP_COMMON_FLAGS; ++ unsigned long flags; + + atomic_set_mask(mask, &port->status); + + if (!common_mask) + return; + +- shost_for_each_device(sdev, port->adapter->scsi_host) ++ spin_lock_irqsave(port->adapter->scsi_host->host_lock, flags); ++ __shost_for_each_device(sdev, port->adapter->scsi_host) + if (sdev_to_zfcp(sdev)->port == port) + atomic_set_mask(common_mask, + &sdev_to_zfcp(sdev)->status); ++ spin_unlock_irqrestore(port->adapter->scsi_host->host_lock, flags); + } + + /** +@@ -1512,6 +1524,7 @@ void zfcp_erp_clear_port_status(struct zfcp_port *port, u32 mask) + struct scsi_device *sdev; + u32 common_mask = mask & ZFCP_COMMON_FLAGS; + u32 clear_counter = mask & ZFCP_STATUS_COMMON_ERP_FAILED; ++ unsigned long flags; + + atomic_clear_mask(mask, &port->status); + +@@ -1521,13 +1534,15 @@ void zfcp_erp_clear_port_status(struct zfcp_port *port, u32 mask) + if (clear_counter) + atomic_set(&port->erp_counter, 0); + +- shost_for_each_device(sdev, port->adapter->scsi_host) ++ spin_lock_irqsave(port->adapter->scsi_host->host_lock, flags); ++ __shost_for_each_device(sdev, port->adapter->scsi_host) + if (sdev_to_zfcp(sdev)->port == port) { + atomic_clear_mask(common_mask, + &sdev_to_zfcp(sdev)->status); + if (clear_counter) + atomic_set(&sdev_to_zfcp(sdev)->erp_counter, 0); + } ++ spin_unlock_irqrestore(port->adapter->scsi_host->host_lock, flags); + } + + /** +diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c +index e76d003..52c6b59 100644 +--- a/drivers/s390/scsi/zfcp_qdio.c ++++ b/drivers/s390/scsi/zfcp_qdio.c +@@ -224,11 +224,9 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req, + + static int zfcp_qdio_sbal_check(struct zfcp_qdio *qdio) + { +- spin_lock_irq(&qdio->req_q_lock); + if (atomic_read(&qdio->req_q_free) || + !(atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)) + return 1; +- spin_unlock_irq(&qdio->req_q_lock); + return 0; + } + +@@ -246,9 +244,8 @@ int zfcp_qdio_sbal_get(struct zfcp_qdio *qdio) + { + long ret; + +- spin_unlock_irq(&qdio->req_q_lock); +- ret = wait_event_interruptible_timeout(qdio->req_q_wq, +- zfcp_qdio_sbal_check(qdio), 5 * HZ); ++ ret = wait_event_interruptible_lock_irq_timeout(qdio->req_q_wq, ++ zfcp_qdio_sbal_check(qdio), qdio->req_q_lock, 5 * HZ); + + if (!(atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)) + return -EIO; +@@ -262,7 +259,6 @@ int zfcp_qdio_sbal_get(struct zfcp_qdio *qdio) + zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdsbg_1"); + } + +- spin_lock_irq(&qdio->req_q_lock); + return -EIO; + } + +diff --git a/drivers/xen/events.c b/drivers/xen/events.c +index 417c133..33dcad6 100644 +--- a/drivers/xen/events.c ++++ b/drivers/xen/events.c +@@ -324,7 +324,7 @@ static void init_evtchn_cpu_bindings(void) + + for_each_possible_cpu(i) + memset(per_cpu(cpu_evtchn_mask, i), +- (i == 0) ? ~0 : 0, sizeof(*per_cpu(cpu_evtchn_mask, i))); ++ (i == 0) ? ~0 : 0, NR_EVENT_CHANNELS/8); + } + + static inline void clear_evtchn(int port) +diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c +index dc9a913..2d8be51 100644 +--- a/fs/nilfs2/segbuf.c ++++ b/fs/nilfs2/segbuf.c +@@ -345,8 +345,7 @@ static void nilfs_end_bio_write(struct bio *bio, int err) + + if (err == -EOPNOTSUPP) { + set_bit(BIO_EOPNOTSUPP, &bio->bi_flags); +- bio_put(bio); +- /* to be detected by submit_seg_bio() */ ++ /* to be detected by nilfs_segbuf_submit_bio() */ + } + + if (!uptodate) +@@ -377,12 +376,12 @@ static int nilfs_segbuf_submit_bio(struct nilfs_segment_buffer *segbuf, + bio->bi_private = segbuf; + bio_get(bio); + submit_bio(mode, bio); ++ segbuf->sb_nbio++; + if (bio_flagged(bio, BIO_EOPNOTSUPP)) { + bio_put(bio); + err = -EOPNOTSUPP; + goto failed; + } +- segbuf->sb_nbio++; + bio_put(bio); + + wi->bio = NULL; +diff --git a/include/linux/wait.h b/include/linux/wait.h +index 6c6c20e..b305b31 100644 +--- a/include/linux/wait.h ++++ b/include/linux/wait.h +@@ -530,6 +530,63 @@ do { \ + ? 0 : __wait_event_interruptible_locked(wq, condition, 1, 1)) + + ++#define __wait_event_interruptible_lock_irq_timeout(wq, condition, \ ++ lock, ret) \ ++do { \ ++ DEFINE_WAIT(__wait); \ ++ \ ++ for (;;) { \ ++ prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE); \ ++ if (condition) \ ++ break; \ ++ if (signal_pending(current)) { \ ++ ret = -ERESTARTSYS; \ ++ break; \ ++ } \ ++ spin_unlock_irq(&lock); \ ++ ret = schedule_timeout(ret); \ ++ spin_lock_irq(&lock); \ ++ if (!ret) \ ++ break; \ ++ } \ ++ finish_wait(&wq, &__wait); \ ++} while (0) ++ ++/** ++ * wait_event_interruptible_lock_irq_timeout - sleep until a condition gets true or a timeout elapses. ++ * The condition is checked under the lock. This is expected ++ * to be called with the lock taken. ++ * @wq: the waitqueue to wait on ++ * @condition: a C expression for the event to wait for ++ * @lock: a locked spinlock_t, which will be released before schedule() ++ * and reacquired afterwards. ++ * @timeout: timeout, in jiffies ++ * ++ * The process is put to sleep (TASK_INTERRUPTIBLE) until the ++ * @condition evaluates to true or signal is received. The @condition is ++ * checked each time the waitqueue @wq is woken up. ++ * ++ * wake_up() has to be called after changing any variable that could ++ * change the result of the wait condition. ++ * ++ * This is supposed to be called while holding the lock. The lock is ++ * dropped before going to sleep and is reacquired afterwards. ++ * ++ * The function returns 0 if the @timeout elapsed, -ERESTARTSYS if it ++ * was interrupted by a signal, and the remaining jiffies otherwise ++ * if the condition evaluated to true before the timeout elapsed. ++ */ ++#define wait_event_interruptible_lock_irq_timeout(wq, condition, lock, \ ++ timeout) \ ++({ \ ++ int __ret = timeout; \ ++ \ ++ if (!(condition)) \ ++ __wait_event_interruptible_lock_irq_timeout( \ ++ wq, condition, lock, __ret); \ ++ __ret; \ ++}) ++ + + #define __wait_event_killable(wq, condition, ret) \ + do { \ +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index a64b94e..575d092 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -128,6 +128,7 @@ struct worker { + }; + + struct work_struct *current_work; /* L: work being processed */ ++ work_func_t current_func; /* L: current_work's fn */ + struct cpu_workqueue_struct *current_cwq; /* L: current_work's cwq */ + struct list_head scheduled; /* L: scheduled works */ + struct task_struct *task; /* I: worker task */ +@@ -838,7 +839,8 @@ static struct worker *__find_worker_executing_work(struct global_cwq *gcwq, + struct hlist_node *tmp; + + hlist_for_each_entry(worker, tmp, bwh, hentry) +- if (worker->current_work == work) ++ if (worker->current_work == work && ++ worker->current_func == work->func) + return worker; + return NULL; + } +@@ -848,9 +850,27 @@ static struct worker *__find_worker_executing_work(struct global_cwq *gcwq, + * @gcwq: gcwq of interest + * @work: work to find worker for + * +- * Find a worker which is executing @work on @gcwq. This function is +- * identical to __find_worker_executing_work() except that this +- * function calculates @bwh itself. ++ * Find a worker which is executing @work on @gcwq by searching ++ * @gcwq->busy_hash which is keyed by the address of @work. For a worker ++ * to match, its current execution should match the address of @work and ++ * its work function. This is to avoid unwanted dependency between ++ * unrelated work executions through a work item being recycled while still ++ * being executed. ++ * ++ * This is a bit tricky. A work item may be freed once its execution ++ * starts and nothing prevents the freed area from being recycled for ++ * another work item. If the same work item address ends up being reused ++ * before the original execution finishes, workqueue will identify the ++ * recycled work item as currently executing and make it wait until the ++ * current execution finishes, introducing an unwanted dependency. ++ * ++ * This function checks the work item address, work function and workqueue ++ * to avoid false positives. Note that this isn't complete as one may ++ * construct a work function which can introduce dependency onto itself ++ * through a recycled work item. Well, if somebody wants to shoot oneself ++ * in the foot that badly, there's only so much we can do, and if such ++ * deadlock actually occurs, it should be easy to locate the culprit work ++ * function. + * + * CONTEXT: + * spin_lock_irq(gcwq->lock). +@@ -1721,10 +1741,9 @@ static void move_linked_works(struct work_struct *work, struct list_head *head, + *nextp = n; + } + +-static void cwq_activate_first_delayed(struct cpu_workqueue_struct *cwq) ++static void cwq_activate_delayed_work(struct work_struct *work) + { +- struct work_struct *work = list_first_entry(&cwq->delayed_works, +- struct work_struct, entry); ++ struct cpu_workqueue_struct *cwq = get_work_cwq(work); + struct list_head *pos = gcwq_determine_ins_pos(cwq->gcwq, cwq); + + trace_workqueue_activate_work(work); +@@ -1733,6 +1752,14 @@ static void cwq_activate_first_delayed(struct cpu_workqueue_struct *cwq) + cwq->nr_active++; + } + ++static void cwq_activate_first_delayed(struct cpu_workqueue_struct *cwq) ++{ ++ struct work_struct *work = list_first_entry(&cwq->delayed_works, ++ struct work_struct, entry); ++ ++ cwq_activate_delayed_work(work); ++} ++ + /** + * cwq_dec_nr_in_flight - decrement cwq's nr_in_flight + * @cwq: cwq of interest +@@ -1804,7 +1831,6 @@ __acquires(&gcwq->lock) + struct global_cwq *gcwq = cwq->gcwq; + struct hlist_head *bwh = busy_worker_head(gcwq, work); + bool cpu_intensive = cwq->wq->flags & WQ_CPU_INTENSIVE; +- work_func_t f = work->func; + int work_color; + struct worker *collision; + #ifdef CONFIG_LOCKDEP +@@ -1833,6 +1859,7 @@ __acquires(&gcwq->lock) + debug_work_deactivate(work); + hlist_add_head(&worker->hentry, bwh); + worker->current_work = work; ++ worker->current_func = work->func; + worker->current_cwq = cwq; + work_color = get_work_color(work); + +@@ -1870,7 +1897,7 @@ __acquires(&gcwq->lock) + lock_map_acquire_read(&cwq->wq->lockdep_map); + lock_map_acquire(&lockdep_map); + trace_workqueue_execute_start(work); +- f(work); ++ worker->current_func(work); + /* + * While we must be careful to not use "work" after this, the trace + * point will only record its address. +@@ -1880,11 +1907,10 @@ __acquires(&gcwq->lock) + lock_map_release(&cwq->wq->lockdep_map); + + if (unlikely(in_atomic() || lockdep_depth(current) > 0)) { +- printk(KERN_ERR "BUG: workqueue leaked lock or atomic: " +- "%s/0x%08x/%d\n", +- current->comm, preempt_count(), task_pid_nr(current)); +- printk(KERN_ERR " last function: "); +- print_symbol("%s\n", (unsigned long)f); ++ pr_err("BUG: workqueue leaked lock or atomic: %s/0x%08x/%d\n" ++ " last function: %pf\n", ++ current->comm, preempt_count(), task_pid_nr(current), ++ worker->current_func); + debug_show_held_locks(current); + dump_stack(); + } +@@ -1898,6 +1924,7 @@ __acquires(&gcwq->lock) + /* we're done with it, release */ + hlist_del_init(&worker->hentry); + worker->current_work = NULL; ++ worker->current_func = NULL; + worker->current_cwq = NULL; + cwq_dec_nr_in_flight(cwq, work_color, false); + } +@@ -2625,6 +2652,18 @@ static int try_to_grab_pending(struct work_struct *work) + smp_rmb(); + if (gcwq == get_work_gcwq(work)) { + debug_work_deactivate(work); ++ ++ /* ++ * A delayed work item cannot be grabbed directly ++ * because it might have linked NO_COLOR work items ++ * which, if left on the delayed_list, will confuse ++ * cwq->nr_active management later on and cause ++ * stall. Make sure the work item is activated ++ * before grabbing. ++ */ ++ if (*work_data_bits(work) & WORK_STRUCT_DELAYED) ++ cwq_activate_delayed_work(work); ++ + list_del_init(&work->entry); + cwq_dec_nr_in_flight(get_work_cwq(work), + get_work_color(work), diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.60-61.patch b/patch/kernel/sun8i-default/0001-patch-3.4.60-61.patch new file mode 100644 index 000000000..6a33f0a3d --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.60-61.patch @@ -0,0 +1,444 @@ +diff --git a/Makefile b/Makefile +index 0027fbe..bc4dd5b 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 60 ++SUBLEVEL = 61 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig +index feab3ba..b17dd69 100644 +--- a/arch/powerpc/Kconfig ++++ b/arch/powerpc/Kconfig +@@ -979,6 +979,7 @@ config RELOCATABLE + must live at a different physical address than the primary + kernel. + ++# This value must have zeroes in the bottom 60 bits otherwise lots will break + config PAGE_OFFSET + hex + default "0xc000000000000000" +diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h +index f072e97..2e6c4e5a 100644 +--- a/arch/powerpc/include/asm/page.h ++++ b/arch/powerpc/include/asm/page.h +@@ -211,9 +211,19 @@ extern long long virt_phys_offset; + #define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) + VIRT_PHYS_OFFSET)) + #define __pa(x) ((unsigned long)(x) - VIRT_PHYS_OFFSET) + #else ++#ifdef CONFIG_PPC64 ++/* ++ * gcc miscompiles (unsigned long)(&static_var) - PAGE_OFFSET ++ * with -mcmodel=medium, so we use & and | instead of - and + on 64-bit. ++ */ ++#define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) | PAGE_OFFSET)) ++#define __pa(x) ((unsigned long)(x) & 0x0fffffffffffffffUL) ++ ++#else /* 32-bit, non book E */ + #define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) + PAGE_OFFSET - MEMORY_START)) + #define __pa(x) ((unsigned long)(x) - PAGE_OFFSET + MEMORY_START) + #endif ++#endif + + /* + * Unfortunately the PLT is in the BSS in the PPC32 ELF ABI, +diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c +index 3251d4b..d1a9674 100644 +--- a/drivers/acpi/ec.c ++++ b/drivers/acpi/ec.c +@@ -978,6 +978,10 @@ static struct dmi_system_id __initdata ec_dmi_table[] = { + ec_skip_dsdt_scan, "HP Folio 13", { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13"),}, NULL}, ++ { ++ ec_validate_ecdt, "ASUS hardware", { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTek Computer Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "L4R"),}, NULL}, + {}, + }; + +diff --git a/drivers/base/memory.c b/drivers/base/memory.c +index 7dda4f7..d63a06b 100644 +--- a/drivers/base/memory.c ++++ b/drivers/base/memory.c +@@ -154,6 +154,8 @@ static ssize_t show_mem_removable(struct device *dev, + container_of(dev, struct memory_block, dev); + + for (i = 0; i < sections_per_block; i++) { ++ if (!present_section_nr(mem->start_section_nr + i)) ++ continue; + pfn = section_nr_to_pfn(mem->start_section_nr + i); + ret &= is_mem_section_removable(pfn, PAGES_PER_SECTION); + } +diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c +index bb80853..ca72d1f 100644 +--- a/drivers/base/regmap/regmap.c ++++ b/drivers/base/regmap/regmap.c +@@ -69,7 +69,7 @@ bool regmap_precious(struct regmap *map, unsigned int reg) + } + + static bool regmap_volatile_range(struct regmap *map, unsigned int reg, +- unsigned int num) ++ size_t num) + { + unsigned int i; + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index d031932..6884d01 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -3741,7 +3741,7 @@ + #define EDP_LINK_TRAIN_600MV_0DB_IVB (0x30 <<22) + #define EDP_LINK_TRAIN_600MV_3_5DB_IVB (0x36 <<22) + #define EDP_LINK_TRAIN_800MV_0DB_IVB (0x38 <<22) +-#define EDP_LINK_TRAIN_800MV_3_5DB_IVB (0x33 <<22) ++#define EDP_LINK_TRAIN_800MV_3_5DB_IVB (0x3e <<22) + + /* legacy values */ + #define EDP_LINK_TRAIN_500MV_0DB_IVB (0x00 <<22) +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c +index 21ee782..e1978a2 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c +@@ -29,7 +29,9 @@ + #include "drmP.h" + #include "ttm/ttm_bo_driver.h" + +-#define VMW_PPN_SIZE sizeof(unsigned long) ++#define VMW_PPN_SIZE (sizeof(unsigned long)) ++/* A future safe maximum remap size. */ ++#define VMW_PPN_PER_REMAP ((31 * 1024) / VMW_PPN_SIZE) + + static int vmw_gmr2_bind(struct vmw_private *dev_priv, + struct page *pages[], +@@ -38,43 +40,61 @@ static int vmw_gmr2_bind(struct vmw_private *dev_priv, + { + SVGAFifoCmdDefineGMR2 define_cmd; + SVGAFifoCmdRemapGMR2 remap_cmd; +- uint32_t define_size = sizeof(define_cmd) + 4; +- uint32_t remap_size = VMW_PPN_SIZE * num_pages + sizeof(remap_cmd) + 4; + uint32_t *cmd; + uint32_t *cmd_orig; ++ uint32_t define_size = sizeof(define_cmd) + sizeof(*cmd); ++ uint32_t remap_num = num_pages / VMW_PPN_PER_REMAP + ((num_pages % VMW_PPN_PER_REMAP) > 0); ++ uint32_t remap_size = VMW_PPN_SIZE * num_pages + (sizeof(remap_cmd) + sizeof(*cmd)) * remap_num; ++ uint32_t remap_pos = 0; ++ uint32_t cmd_size = define_size + remap_size; + uint32_t i; + +- cmd_orig = cmd = vmw_fifo_reserve(dev_priv, define_size + remap_size); ++ cmd_orig = cmd = vmw_fifo_reserve(dev_priv, cmd_size); + if (unlikely(cmd == NULL)) + return -ENOMEM; + + define_cmd.gmrId = gmr_id; + define_cmd.numPages = num_pages; + ++ *cmd++ = SVGA_CMD_DEFINE_GMR2; ++ memcpy(cmd, &define_cmd, sizeof(define_cmd)); ++ cmd += sizeof(define_cmd) / sizeof(*cmd); ++ ++ /* ++ * Need to split the command if there are too many ++ * pages that goes into the gmr. ++ */ ++ + remap_cmd.gmrId = gmr_id; + remap_cmd.flags = (VMW_PPN_SIZE > sizeof(*cmd)) ? + SVGA_REMAP_GMR2_PPN64 : SVGA_REMAP_GMR2_PPN32; +- remap_cmd.offsetPages = 0; +- remap_cmd.numPages = num_pages; + +- *cmd++ = SVGA_CMD_DEFINE_GMR2; +- memcpy(cmd, &define_cmd, sizeof(define_cmd)); +- cmd += sizeof(define_cmd) / sizeof(uint32); ++ while (num_pages > 0) { ++ unsigned long nr = min(num_pages, (unsigned long)VMW_PPN_PER_REMAP); ++ ++ remap_cmd.offsetPages = remap_pos; ++ remap_cmd.numPages = nr; + +- *cmd++ = SVGA_CMD_REMAP_GMR2; +- memcpy(cmd, &remap_cmd, sizeof(remap_cmd)); +- cmd += sizeof(remap_cmd) / sizeof(uint32); ++ *cmd++ = SVGA_CMD_REMAP_GMR2; ++ memcpy(cmd, &remap_cmd, sizeof(remap_cmd)); ++ cmd += sizeof(remap_cmd) / sizeof(*cmd); + +- for (i = 0; i < num_pages; ++i) { +- if (VMW_PPN_SIZE <= 4) +- *cmd = page_to_pfn(*pages++); +- else +- *((uint64_t *)cmd) = page_to_pfn(*pages++); ++ for (i = 0; i < nr; ++i) { ++ if (VMW_PPN_SIZE <= 4) ++ *cmd = page_to_pfn(*pages++); ++ else ++ *((uint64_t *)cmd) = page_to_pfn(*pages++); + +- cmd += VMW_PPN_SIZE / sizeof(*cmd); ++ cmd += VMW_PPN_SIZE / sizeof(*cmd); ++ } ++ ++ num_pages -= nr; ++ remap_pos += nr; + } + +- vmw_fifo_commit(dev_priv, define_size + remap_size); ++ BUG_ON(cmd != cmd_orig + cmd_size / sizeof(*cmd)); ++ ++ vmw_fifo_commit(dev_priv, cmd_size); + + return 0; + } +diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +index 3e40a64..b290a8e 100644 +--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c ++++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +@@ -448,6 +448,7 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv, + struct ieee80211_conf *cur_conf = &priv->hw->conf; + bool txok; + int slot; ++ int hdrlen, padsize; + + slot = strip_drv_header(priv, skb); + if (slot < 0) { +@@ -504,6 +505,15 @@ send_mac80211: + + ath9k_htc_tx_clear_slot(priv, slot); + ++ /* Remove padding before handing frame back to mac80211 */ ++ hdrlen = ieee80211_get_hdrlen_from_skb(skb); ++ ++ padsize = hdrlen & 3; ++ if (padsize && skb->len > hdrlen + padsize) { ++ memmove(skb->data + padsize, skb->data, hdrlen); ++ skb_pull(skb, padsize); ++ } ++ + /* Send status to mac80211 */ + ieee80211_tx_status(priv->hw, skb); + } +diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c +index 409ed06..3223daa 100644 +--- a/drivers/net/wireless/iwlegacy/4965-mac.c ++++ b/drivers/net/wireless/iwlegacy/4965-mac.c +@@ -4415,9 +4415,9 @@ il4965_irq_tasklet(struct il_priv *il) + set_bit(S_RFKILL, &il->status); + } else { + clear_bit(S_RFKILL, &il->status); +- wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rf_kill); + il_force_reset(il, true); + } ++ wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rf_kill); + + handled |= CSR_INT_BIT_RF_KILL; + } +diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c +index 52a5f62..2d88ce8 100644 +--- a/drivers/target/target_core_cdb.c ++++ b/drivers/target/target_core_cdb.c +@@ -97,9 +97,12 @@ target_emulate_inquiry_std(struct se_cmd *cmd, char *buf) + + buf[7] = 0x2; /* CmdQue=1 */ + +- snprintf(&buf[8], 8, "LIO-ORG"); +- snprintf(&buf[16], 16, "%s", dev->se_sub_dev->t10_wwn.model); +- snprintf(&buf[32], 4, "%s", dev->se_sub_dev->t10_wwn.revision); ++ memcpy(&buf[8], "LIO-ORG ", 8); ++ memset(&buf[16], 0x20, 16); ++ memcpy(&buf[16], dev->se_sub_dev->t10_wwn.model, ++ min_t(size_t, strlen(dev->se_sub_dev->t10_wwn.model), 16)); ++ memcpy(&buf[32], dev->se_sub_dev->t10_wwn.revision, ++ min_t(size_t, strlen(dev->se_sub_dev->t10_wwn.revision), 4)); + buf[4] = 31; /* Set additional length to 31 */ + + return 0; +diff --git a/drivers/tty/hvc/hvsi_lib.c b/drivers/tty/hvc/hvsi_lib.c +index 6f4dd83..3749688 100644 +--- a/drivers/tty/hvc/hvsi_lib.c ++++ b/drivers/tty/hvc/hvsi_lib.c +@@ -341,8 +341,8 @@ void hvsilib_establish(struct hvsi_priv *pv) + + pr_devel("HVSI@%x: ... waiting handshake\n", pv->termno); + +- /* Try for up to 200s */ +- for (timeout = 0; timeout < 20; timeout++) { ++ /* Try for up to 400ms */ ++ for (timeout = 0; timeout < 40; timeout++) { + if (pv->established) + goto established; + if (!hvsi_get_packet(pv)) +diff --git a/fs/bio.c b/fs/bio.c +index 84da885..c0e5a4e 100644 +--- a/fs/bio.c ++++ b/fs/bio.c +@@ -787,12 +787,22 @@ static int __bio_copy_iov(struct bio *bio, struct bio_vec *iovecs, + int bio_uncopy_user(struct bio *bio) + { + struct bio_map_data *bmd = bio->bi_private; +- int ret = 0; ++ struct bio_vec *bvec; ++ int ret = 0, i; + +- if (!bio_flagged(bio, BIO_NULL_MAPPED)) +- ret = __bio_copy_iov(bio, bmd->iovecs, bmd->sgvecs, +- bmd->nr_sgvecs, bio_data_dir(bio) == READ, +- 0, bmd->is_our_pages); ++ if (!bio_flagged(bio, BIO_NULL_MAPPED)) { ++ /* ++ * if we're in a workqueue, the request is orphaned, so ++ * don't copy into a random user address space, just free. ++ */ ++ if (current->mm) ++ ret = __bio_copy_iov(bio, bmd->iovecs, bmd->sgvecs, ++ bmd->nr_sgvecs, bio_data_dir(bio) == READ, ++ 0, bmd->is_our_pages); ++ else if (bmd->is_our_pages) ++ __bio_for_each_segment(bvec, bio, i, 0) ++ __free_page(bvec->bv_page); ++ } + bio_free_map_data(bmd); + bio_put(bio); + return ret; +diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c +index 9197a1b..b6f17c0 100644 +--- a/fs/jfs/jfs_dtree.c ++++ b/fs/jfs/jfs_dtree.c +@@ -3047,6 +3047,14 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) + + dir_index = (u32) filp->f_pos; + ++ /* ++ * NFSv4 reserves cookies 1 and 2 for . and .. so we add ++ * the value we return to the vfs is one greater than the ++ * one we use internally. ++ */ ++ if (dir_index) ++ dir_index--; ++ + if (dir_index > 1) { + struct dir_table_slot dirtab_slot; + +@@ -3086,7 +3094,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) + if (p->header.flag & BT_INTERNAL) { + jfs_err("jfs_readdir: bad index table"); + DT_PUTPAGE(mp); +- filp->f_pos = -1; ++ filp->f_pos = DIREND; + return 0; + } + } else { +@@ -3094,7 +3102,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) + /* + * self "." + */ +- filp->f_pos = 0; ++ filp->f_pos = 1; + if (filldir(dirent, ".", 1, 0, ip->i_ino, + DT_DIR)) + return 0; +@@ -3102,7 +3110,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) + /* + * parent ".." + */ +- filp->f_pos = 1; ++ filp->f_pos = 2; + if (filldir(dirent, "..", 2, 1, PARENT(ip), DT_DIR)) + return 0; + +@@ -3123,24 +3131,25 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) + /* + * Legacy filesystem - OS/2 & Linux JFS < 0.3.6 + * +- * pn = index = 0: First entry "." +- * pn = 0; index = 1: Second entry ".." ++ * pn = 0; index = 1: First entry "." ++ * pn = 0; index = 2: Second entry ".." + * pn > 0: Real entries, pn=1 -> leftmost page + * pn = index = -1: No more entries + */ + dtpos = filp->f_pos; +- if (dtpos == 0) { ++ if (dtpos < 2) { + /* build "." entry */ + ++ filp->f_pos = 1; + if (filldir(dirent, ".", 1, filp->f_pos, ip->i_ino, + DT_DIR)) + return 0; +- dtoffset->index = 1; ++ dtoffset->index = 2; + filp->f_pos = dtpos; + } + + if (dtoffset->pn == 0) { +- if (dtoffset->index == 1) { ++ if (dtoffset->index == 2) { + /* build ".." entry */ + + if (filldir(dirent, "..", 2, filp->f_pos, +@@ -3233,6 +3242,12 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) + } + jfs_dirent->position = unique_pos++; + } ++ /* ++ * We add 1 to the index because we may ++ * use a value of 2 internally, and NFSv4 ++ * doesn't like that. ++ */ ++ jfs_dirent->position++; + } else { + jfs_dirent->position = dtpos; + len = min(d_namleft, DTLHDRDATALEN_LEGACY); +diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c +index b97a3dd..6997cdd 100644 +--- a/net/sunrpc/xdr.c ++++ b/net/sunrpc/xdr.c +@@ -233,10 +233,13 @@ _shift_data_right_pages(struct page **pages, size_t pgto_base, + pgfrom_base -= copy; + + vto = kmap_atomic(*pgto); +- vfrom = kmap_atomic(*pgfrom); +- memmove(vto + pgto_base, vfrom + pgfrom_base, copy); ++ if (*pgto != *pgfrom) { ++ vfrom = kmap_atomic(*pgfrom); ++ memcpy(vto + pgto_base, vfrom + pgfrom_base, copy); ++ kunmap_atomic(vfrom); ++ } else ++ memmove(vto + pgto_base, vto + pgfrom_base, copy); + flush_dcache_page(*pgto); +- kunmap_atomic(vfrom); + kunmap_atomic(vto); + + } while ((len -= copy) != 0); +diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c +index d7ccf28..4589acd 100644 +--- a/sound/isa/opti9xx/opti92x-ad1848.c ++++ b/sound/isa/opti9xx/opti92x-ad1848.c +@@ -173,11 +173,7 @@ MODULE_DEVICE_TABLE(pnp_card, snd_opti9xx_pnpids); + + #endif /* CONFIG_PNP */ + +-#ifdef OPTi93X +-#define DEV_NAME "opti93x" +-#else +-#define DEV_NAME "opti92x" +-#endif ++#define DEV_NAME KBUILD_MODNAME + + static char * snd_opti9xx_names[] = { + "unknown", +@@ -1126,7 +1122,7 @@ static void __devexit snd_opti9xx_pnp_remove(struct pnp_card_link * pcard) + + static struct pnp_card_driver opti9xx_pnpc_driver = { + .flags = PNP_DRIVER_RES_DISABLE, +- .name = "opti9xx", ++ .name = DEV_NAME, + .id_table = snd_opti9xx_pnpids, + .probe = snd_opti9xx_pnp_probe, + .remove = __devexit_p(snd_opti9xx_pnp_remove), diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.61-62.patch b/patch/kernel/sun8i-default/0001-patch-3.4.61-62.patch new file mode 100644 index 000000000..dd4a10f40 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.61-62.patch @@ -0,0 +1,567 @@ +diff --git a/Makefile b/Makefile +index bc4dd5b..3f23cb7 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 61 ++SUBLEVEL = 62 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/m32r/boot/compressed/Makefile b/arch/m32r/boot/compressed/Makefile +index 177716b..01729c2 100644 +--- a/arch/m32r/boot/compressed/Makefile ++++ b/arch/m32r/boot/compressed/Makefile +@@ -43,9 +43,9 @@ endif + + OBJCOPYFLAGS += -R .empty_zero_page + +-suffix_$(CONFIG_KERNEL_GZIP) = gz +-suffix_$(CONFIG_KERNEL_BZIP2) = bz2 +-suffix_$(CONFIG_KERNEL_LZMA) = lzma ++suffix-$(CONFIG_KERNEL_GZIP) = gz ++suffix-$(CONFIG_KERNEL_BZIP2) = bz2 ++suffix-$(CONFIG_KERNEL_LZMA) = lzma + + $(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) FORCE + $(call if_changed,ld) +diff --git a/arch/m32r/boot/compressed/misc.c b/arch/m32r/boot/compressed/misc.c +index 370d608..28a0952 100644 +--- a/arch/m32r/boot/compressed/misc.c ++++ b/arch/m32r/boot/compressed/misc.c +@@ -28,7 +28,7 @@ static unsigned long free_mem_ptr; + static unsigned long free_mem_end_ptr; + + #ifdef CONFIG_KERNEL_BZIP2 +-static void *memset(void *s, int c, size_t n) ++void *memset(void *s, int c, size_t n) + { + char *ss = s; + +@@ -39,6 +39,16 @@ static void *memset(void *s, int c, size_t n) + #endif + + #ifdef CONFIG_KERNEL_GZIP ++void *memcpy(void *dest, const void *src, size_t n) ++{ ++ char *d = dest; ++ const char *s = src; ++ while (n--) ++ *d++ = *s++; ++ ++ return dest; ++} ++ + #define BOOT_HEAP_SIZE 0x10000 + #include "../../../../lib/decompress_inflate.c" + #endif +diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c +index 8c45818..8375622 100644 +--- a/arch/x86/kvm/emulate.c ++++ b/arch/x86/kvm/emulate.c +@@ -3737,10 +3737,6 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op, + break; + case OpMem8: + ctxt->memop.bytes = 1; +- if (ctxt->memop.type == OP_REG) { +- ctxt->memop.addr.reg = decode_register(ctxt, ctxt->modrm_rm, 1); +- fetch_register_operand(&ctxt->memop); +- } + goto mem_common; + case OpMem16: + ctxt->memop.bytes = 2; +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index d9f8358..80103bb 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -3750,11 +3750,17 @@ static int bond_neigh_init(struct neighbour *n) + * The bonding ndo_neigh_setup is called at init time beofre any + * slave exists. So we must declare proxy setup function which will + * be used at run time to resolve the actual slave neigh param setup. ++ * ++ * It's also called by master devices (such as vlans) to setup their ++ * underlying devices. In that case - do nothing, we're already set up from ++ * our init. + */ + static int bond_neigh_setup(struct net_device *dev, + struct neigh_parms *parms) + { +- parms->neigh_setup = bond_neigh_init; ++ /* modify only our neigh_parms */ ++ if (parms->dev == dev) ++ parms->neigh_setup = bond_neigh_init; + + return 0; + } +diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c +index 2205db7..1b44047 100644 +--- a/drivers/net/ethernet/realtek/8139cp.c ++++ b/drivers/net/ethernet/realtek/8139cp.c +@@ -524,6 +524,7 @@ rx_status_loop: + PCI_DMA_FROMDEVICE); + if (dma_mapping_error(&cp->pdev->dev, new_mapping)) { + dev->stats.rx_dropped++; ++ kfree_skb(new_skb); + goto rx_next; + } + +diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c +index 5151f06..77ce8b2 100644 +--- a/drivers/net/macvtap.c ++++ b/drivers/net/macvtap.c +@@ -642,6 +642,28 @@ static int macvtap_skb_to_vnet_hdr(const struct sk_buff *skb, + return 0; + } + ++static unsigned long iov_pages(const struct iovec *iv, int offset, ++ unsigned long nr_segs) ++{ ++ unsigned long seg, base; ++ int pages = 0, len, size; ++ ++ while (nr_segs && (offset >= iv->iov_len)) { ++ offset -= iv->iov_len; ++ ++iv; ++ --nr_segs; ++ } ++ ++ for (seg = 0; seg < nr_segs; seg++) { ++ base = (unsigned long)iv[seg].iov_base + offset; ++ len = iv[seg].iov_len - offset; ++ size = ((base & ~PAGE_MASK) + len + ~PAGE_MASK) >> PAGE_SHIFT; ++ pages += size; ++ offset = 0; ++ } ++ ++ return pages; ++} + + /* Get packet from user space buffer */ + static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, +@@ -688,31 +710,15 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, + if (unlikely(count > UIO_MAXIOV)) + goto err; + +- if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY)) +- zerocopy = true; +- +- if (zerocopy) { +- /* Userspace may produce vectors with count greater than +- * MAX_SKB_FRAGS, so we need to linearize parts of the skb +- * to let the rest of data to be fit in the frags. +- */ +- if (count > MAX_SKB_FRAGS) { +- copylen = iov_length(iv, count - MAX_SKB_FRAGS); +- if (copylen < vnet_hdr_len) +- copylen = 0; +- else +- copylen -= vnet_hdr_len; +- } +- /* There are 256 bytes to be copied in skb, so there is enough +- * room for skb expand head in case it is used. +- * The rest buffer is mapped from userspace. +- */ +- if (copylen < vnet_hdr.hdr_len) +- copylen = vnet_hdr.hdr_len; +- if (!copylen) +- copylen = GOODCOPY_LEN; ++ if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY)) { ++ copylen = vnet_hdr.hdr_len ? vnet_hdr.hdr_len : GOODCOPY_LEN; + linear = copylen; +- } else { ++ if (iov_pages(iv, vnet_hdr_len + copylen, count) ++ <= MAX_SKB_FRAGS) ++ zerocopy = true; ++ } ++ ++ if (!zerocopy) { + copylen = len; + linear = vnet_hdr.hdr_len; + } +@@ -724,9 +730,15 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, + + if (zerocopy) + err = zerocopy_sg_from_iovec(skb, iv, vnet_hdr_len, count); +- else ++ else { + err = skb_copy_datagram_from_iovec(skb, 0, iv, vnet_hdr_len, + len); ++ if (!err && m && m->msg_control) { ++ struct ubuf_info *uarg = m->msg_control; ++ uarg->callback(uarg); ++ } ++ } ++ + if (err) + goto err_kfree; + +diff --git a/drivers/net/tun.c b/drivers/net/tun.c +index c896b8f..194f879 100644 +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -615,8 +615,9 @@ static ssize_t tun_get_user(struct tun_struct *tun, + int offset = 0; + + if (!(tun->flags & TUN_NO_PI)) { +- if ((len -= sizeof(pi)) > count) ++ if (len < sizeof(pi)) + return -EINVAL; ++ len -= sizeof(pi); + + if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi))) + return -EFAULT; +@@ -624,8 +625,9 @@ static ssize_t tun_get_user(struct tun_struct *tun, + } + + if (tun->flags & TUN_VNET_HDR) { +- if ((len -= tun->vnet_hdr_sz) > count) ++ if (len < tun->vnet_hdr_sz) + return -EINVAL; ++ len -= tun->vnet_hdr_sz; + + if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso))) + return -EFAULT; +diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c +index 1a9e2a9..a50cb9c 100644 +--- a/drivers/vhost/vhost.c ++++ b/drivers/vhost/vhost.c +@@ -1603,6 +1603,7 @@ void vhost_zerocopy_callback(struct ubuf_info *ubuf) + struct vhost_ubuf_ref *ubufs = ubuf->ctx; + struct vhost_virtqueue *vq = ubufs->vq; + ++ vhost_poll_queue(&vq->poll); + /* set len = 1 to mark this desc buffers done DMA */ + vq->heads[ubuf->desc].len = VHOST_DMA_DONE_LEN; + kref_put(&ubufs->kref, vhost_zerocopy_done_signal); +diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h +index ba45e6b..f5a21d0 100644 +--- a/include/linux/icmpv6.h ++++ b/include/linux/icmpv6.h +@@ -123,6 +123,8 @@ static inline struct icmp6hdr *icmp6_hdr(const struct sk_buff *skb) + #define ICMPV6_NOT_NEIGHBOUR 2 + #define ICMPV6_ADDR_UNREACH 3 + #define ICMPV6_PORT_UNREACH 4 ++#define ICMPV6_POLICY_FAIL 5 ++#define ICMPV6_REJECT_ROUTE 6 + + /* + * Codes for Time Exceeded +diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c +index 9069071..ca670d9 100644 +--- a/net/bridge/br_multicast.c ++++ b/net/bridge/br_multicast.c +@@ -1155,7 +1155,8 @@ static int br_ip6_multicast_query(struct net_bridge *br, + mld2q = (struct mld2_query *)icmp6_hdr(skb); + if (!mld2q->mld2q_nsrcs) + group = &mld2q->mld2q_mca; +- max_delay = mld2q->mld2q_mrc ? MLDV2_MRC(mld2q->mld2q_mrc) : 1; ++ ++ max_delay = max(msecs_to_jiffies(MLDV2_MRC(ntohs(mld2q->mld2q_mrc))), 1UL); + } + + if (!group) +diff --git a/net/core/neighbour.c b/net/core/neighbour.c +index 69b7ca3..ebd4b21 100644 +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -1442,16 +1442,18 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev, + atomic_set(&p->refcnt, 1); + p->reachable_time = + neigh_rand_reach_time(p->base_reachable_time); ++ dev_hold(dev); ++ p->dev = dev; ++ write_pnet(&p->net, hold_net(net)); ++ p->sysctl_table = NULL; + + if (ops->ndo_neigh_setup && ops->ndo_neigh_setup(dev, p)) { ++ release_net(net); ++ dev_put(dev); + kfree(p); + return NULL; + } + +- dev_hold(dev); +- p->dev = dev; +- write_pnet(&p->net, hold_net(net)); +- p->sysctl_table = NULL; + write_lock_bh(&tbl->lock); + p->next = tbl->parms.next; + tbl->parms.next = p; +diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c +index 0c28508..77d1550 100644 +--- a/net/core/sysctl_net_core.c ++++ b/net/core/sysctl_net_core.c +@@ -19,6 +19,9 @@ + #include + #include + ++static int zero = 0; ++static int ushort_max = USHRT_MAX; ++ + #ifdef CONFIG_RPS + static int rps_sock_flow_sysctl(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +@@ -197,7 +200,9 @@ static struct ctl_table netns_core_table[] = { + .data = &init_net.core.sysctl_somaxconn, + .maxlen = sizeof(int), + .mode = 0644, +- .proc_handler = proc_dointvec ++ .extra1 = &zero, ++ .extra2 = &ushort_max, ++ .proc_handler = proc_dointvec_minmax + }, + { } + }; +diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c +index 30b88d7..424704a 100644 +--- a/net/ipv4/fib_trie.c ++++ b/net/ipv4/fib_trie.c +@@ -71,7 +71,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -1772,10 +1771,8 @@ static struct leaf *leaf_walk_rcu(struct tnode *p, struct rt_trie_node *c) + if (!c) + continue; + +- if (IS_LEAF(c)) { +- prefetch(rcu_dereference_rtnl(p->child[idx])); ++ if (IS_LEAF(c)) + return (struct leaf *) c; +- } + + /* Rescan start scanning in new node */ + p = (struct tnode *) c; +diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c +index a9077f4..b6ae92a 100644 +--- a/net/ipv4/tcp_cubic.c ++++ b/net/ipv4/tcp_cubic.c +@@ -206,8 +206,8 @@ static u32 cubic_root(u64 a) + */ + static inline void bictcp_update(struct bictcp *ca, u32 cwnd) + { +- u64 offs; +- u32 delta, t, bic_target, max_cnt; ++ u32 delta, bic_target, max_cnt; ++ u64 offs, t; + + ca->ack_cnt++; /* count the number of ACKs */ + +@@ -250,9 +250,11 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd) + * if the cwnd < 1 million packets !!! + */ + ++ t = (s32)(tcp_time_stamp - ca->epoch_start); ++ t += msecs_to_jiffies(ca->delay_min >> 3); + /* change the unit from HZ to bictcp_HZ */ +- t = ((tcp_time_stamp + msecs_to_jiffies(ca->delay_min>>3) +- - ca->epoch_start) << BICTCP_HZ) / HZ; ++ t <<= BICTCP_HZ; ++ do_div(t, HZ); + + if (t < ca->bic_K) /* t - K */ + offs = ca->bic_K - t; +@@ -414,7 +416,7 @@ static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt_us) + return; + + /* Discard delay samples right after fast recovery */ +- if ((s32)(tcp_time_stamp - ca->epoch_start) < HZ) ++ if (ca->epoch_start && (s32)(tcp_time_stamp - ca->epoch_start) < HZ) + return; + + delay = (rtt_us << 3) / USEC_PER_MSEC; +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index d427f1b..abfa007 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -910,12 +910,10 @@ retry: + if (ifp->flags & IFA_F_OPTIMISTIC) + addr_flags |= IFA_F_OPTIMISTIC; + +- ift = !max_addresses || +- ipv6_count_addresses(idev) < max_addresses ? +- ipv6_add_addr(idev, &addr, tmp_plen, +- ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, +- addr_flags) : NULL; +- if (!ift || IS_ERR(ift)) { ++ ift = ipv6_add_addr(idev, &addr, tmp_plen, ++ ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, ++ addr_flags); ++ if (IS_ERR(ift)) { + in6_ifa_put(ifp); + in6_dev_put(idev); + printk(KERN_INFO +diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c +index 27ac95a..dbf20f6 100644 +--- a/net/ipv6/icmp.c ++++ b/net/ipv6/icmp.c +@@ -917,6 +917,14 @@ static const struct icmp6_err { + .err = ECONNREFUSED, + .fatal = 1, + }, ++ { /* POLICY_FAIL */ ++ .err = EACCES, ++ .fatal = 1, ++ }, ++ { /* REJECT_ROUTE */ ++ .err = EACCES, ++ .fatal = 1, ++ }, + }; + + int icmpv6_err_convert(u8 type, u8 code, int *err) +@@ -928,7 +936,7 @@ int icmpv6_err_convert(u8 type, u8 code, int *err) + switch (type) { + case ICMPV6_DEST_UNREACH: + fatal = 1; +- if (code <= ICMPV6_PORT_UNREACH) { ++ if (code < ARRAY_SIZE(tab_unreach)) { + *err = tab_unreach[code].err; + fatal = tab_unreach[code].fatal; + } +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index c3a007d..5bb77a6 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -949,14 +949,22 @@ static struct fib6_node * fib6_lookup_1(struct fib6_node *root, + + if (ipv6_prefix_equal(&key->addr, args->addr, key->plen)) { + #ifdef CONFIG_IPV6_SUBTREES +- if (fn->subtree) +- fn = fib6_lookup_1(fn->subtree, args + 1); ++ if (fn->subtree) { ++ struct fib6_node *sfn; ++ sfn = fib6_lookup_1(fn->subtree, ++ args + 1); ++ if (!sfn) ++ goto backtrack; ++ fn = sfn; ++ } + #endif +- if (!fn || fn->fn_flags & RTN_RTINFO) ++ if (fn->fn_flags & RTN_RTINFO) + return fn; + } + } +- ++#ifdef CONFIG_IPV6_SUBTREES ++backtrack: ++#endif + if (fn->fn_flags & RTN_ROOT) + break; + +diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c +index 843d6eb..5cc78e6 100644 +--- a/net/ipv6/ndisc.c ++++ b/net/ipv6/ndisc.c +@@ -441,7 +441,6 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev, + int hlen = LL_RESERVED_SPACE(dev); + int tlen = dev->needed_tailroom; + int len; +- int err; + u8 *opt; + + if (!dev->addr_len) +@@ -451,14 +450,12 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev, + if (llinfo) + len += ndisc_opt_addr_space(dev); + +- skb = sock_alloc_send_skb(sk, +- (MAX_HEADER + sizeof(struct ipv6hdr) + +- len + hlen + tlen), +- 1, &err); ++ skb = alloc_skb((MAX_HEADER + sizeof(struct ipv6hdr) + ++ len + hlen + tlen), GFP_ATOMIC); + if (!skb) { + ND_PRINTK0(KERN_ERR +- "ICMPv6 ND: %s() failed to allocate an skb, err=%d.\n", +- __func__, err); ++ "ICMPv6 ND: %s() failed to allocate an skb.\n", ++ __func__); + return NULL; + } + +@@ -486,6 +483,11 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev, + csum_partial(hdr, + len, 0)); + ++ /* Manually assign socket ownership as we avoid calling ++ * sock_alloc_send_pskb() to bypass wmem buffer limits ++ */ ++ skb_set_owner_w(skb, sk); ++ + return skb; + } + +diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c +index 7ee7121..c4717e8 100644 +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -1571,7 +1571,7 @@ ipv6_pktoptions: + if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) + np->mcast_hops = ipv6_hdr(opt_skb)->hop_limit; + if (np->rxopt.bits.rxtclass) +- np->rcv_tclass = ipv6_tclass(ipv6_hdr(skb)); ++ np->rcv_tclass = ipv6_tclass(ipv6_hdr(opt_skb)); + if (ipv6_opt_accepted(sk, opt_skb)) { + skb_set_owner_r(opt_skb, sk); + opt_skb = xchg(&np->pktoptions, opt_skb); +diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c +index f08b9166..caa5aff 100644 +--- a/net/sched/sch_htb.c ++++ b/net/sched/sch_htb.c +@@ -86,7 +86,7 @@ struct htb_class { + unsigned int children; + struct htb_class *parent; /* parent class */ + +- int prio; /* these two are used only by leaves... */ ++ u32 prio; /* these two are used only by leaves... */ + int quantum; /* but stored for parent-to-leaf return */ + + union { +diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c +index 527e3f0..dd625af 100644 +--- a/net/tipc/eth_media.c ++++ b/net/tipc/eth_media.c +@@ -53,6 +53,7 @@ struct eth_bearer { + struct tipc_bearer *bearer; + struct net_device *dev; + struct packet_type tipc_packet_type; ++ struct work_struct setup; + struct work_struct cleanup; + }; + +@@ -138,6 +139,17 @@ static int recv_msg(struct sk_buff *buf, struct net_device *dev, + } + + /** ++ * setup_bearer - setup association between Ethernet bearer and interface ++ */ ++static void setup_bearer(struct work_struct *work) ++{ ++ struct eth_bearer *eb_ptr = ++ container_of(work, struct eth_bearer, setup); ++ ++ dev_add_pack(&eb_ptr->tipc_packet_type); ++} ++ ++/** + * enable_bearer - attach TIPC bearer to an Ethernet interface + */ + +@@ -181,7 +193,8 @@ static int enable_bearer(struct tipc_bearer *tb_ptr) + eb_ptr->tipc_packet_type.func = recv_msg; + eb_ptr->tipc_packet_type.af_packet_priv = eb_ptr; + INIT_LIST_HEAD(&(eb_ptr->tipc_packet_type.list)); +- dev_add_pack(&eb_ptr->tipc_packet_type); ++ INIT_WORK(&eb_ptr->setup, setup_bearer); ++ schedule_work(&eb_ptr->setup); + + /* Associate TIPC bearer with Ethernet bearer */ + diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.62-63.patch b/patch/kernel/sun8i-default/0001-patch-3.4.62-63.patch new file mode 100644 index 000000000..9d8192642 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.62-63.patch @@ -0,0 +1,1055 @@ +diff --git a/Makefile b/Makefile +index 3f23cb7e..94ce9416 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 62 ++SUBLEVEL = 63 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c +index d2268be8..709beb1d 100644 +--- a/arch/arm/mach-versatile/pci.c ++++ b/arch/arm/mach-versatile/pci.c +@@ -42,9 +42,9 @@ + #define PCI_IMAP0 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x0) + #define PCI_IMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x4) + #define PCI_IMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x8) +-#define PCI_SMAP0 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x10) +-#define PCI_SMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14) +-#define PCI_SMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18) ++#define PCI_SMAP0 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14) ++#define PCI_SMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18) ++#define PCI_SMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x1c) + #define PCI_SELFID __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0xc) + + #define DEVICE_ID_OFFSET 0x00 +diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c +index 54d0eb4db..89276a2f 100644 +--- a/arch/mips/ath79/clock.c ++++ b/arch/mips/ath79/clock.c +@@ -159,7 +159,7 @@ static void __init ar933x_clocks_init(void) + ath79_ahb_clk.rate = freq / t; + } + +- ath79_wdt_clk.rate = ath79_ref_clk.rate; ++ ath79_wdt_clk.rate = ath79_ahb_clk.rate; + ath79_uart_clk.rate = ath79_ref_clk.rate; + } + +diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c +index ee5b690a..52e5758e 100644 +--- a/arch/powerpc/kernel/align.c ++++ b/arch/powerpc/kernel/align.c +@@ -764,6 +764,16 @@ int fix_alignment(struct pt_regs *regs) + nb = aligninfo[instr].len; + flags = aligninfo[instr].flags; + ++ /* ldbrx/stdbrx overlap lfs/stfs in the DSISR unfortunately */ ++ if (IS_XFORM(instruction) && ((instruction >> 1) & 0x3ff) == 532) { ++ nb = 8; ++ flags = LD+SW; ++ } else if (IS_XFORM(instruction) && ++ ((instruction >> 1) & 0x3ff) == 660) { ++ nb = 8; ++ flags = ST+SW; ++ } ++ + /* Byteswap little endian loads and stores */ + swiz = 0; + if (regs->msr & MSR_LE) { +diff --git a/crypto/api.c b/crypto/api.c +index 033a7147..4f98dd5b 100644 +--- a/crypto/api.c ++++ b/crypto/api.c +@@ -40,6 +40,8 @@ static inline struct crypto_alg *crypto_alg_get(struct crypto_alg *alg) + return alg; + } + ++static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg); ++ + struct crypto_alg *crypto_mod_get(struct crypto_alg *alg) + { + return try_module_get(alg->cra_module) ? crypto_alg_get(alg) : NULL; +@@ -150,8 +152,11 @@ static struct crypto_alg *crypto_larval_add(const char *name, u32 type, + } + up_write(&crypto_alg_sem); + +- if (alg != &larval->alg) ++ if (alg != &larval->alg) { + kfree(larval); ++ if (crypto_is_larval(alg)) ++ alg = crypto_larval_wait(alg); ++ } + + return alg; + } +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index 8b77fd31..efe172f3 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -125,6 +125,9 @@ static struct edid_quirk { + + /* ViewSonic VA2026w */ + { "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING }, ++ ++ /* Medion MD 30217 PG */ ++ { "MED", 0x7b8, EDID_QUIRK_PREFER_LARGE_75 }, + }; + + /*** DDC fetch and block validation ***/ +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index ff73d60c..ab59fdf0 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -63,6 +63,8 @@ struct hid_report *hid_register_report(struct hid_device *device, unsigned type, + struct hid_report_enum *report_enum = device->report_enum + type; + struct hid_report *report; + ++ if (id >= HID_MAX_IDS) ++ return NULL; + if (report_enum->report_id_hash[id]) + return report_enum->report_id_hash[id]; + +@@ -385,8 +387,10 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) + + case HID_GLOBAL_ITEM_TAG_REPORT_ID: + parser->global.report_id = item_udata(item); +- if (parser->global.report_id == 0) { +- hid_err(parser->device, "report_id 0 is invalid\n"); ++ if (parser->global.report_id == 0 || ++ parser->global.report_id >= HID_MAX_IDS) { ++ hid_err(parser->device, "report_id %u is invalid\n", ++ parser->global.report_id); + return -1; + } + return 0; +@@ -557,7 +561,7 @@ static void hid_device_release(struct device *dev) + for (i = 0; i < HID_REPORT_TYPES; i++) { + struct hid_report_enum *report_enum = device->report_enum + i; + +- for (j = 0; j < 256; j++) { ++ for (j = 0; j < HID_MAX_IDS; j++) { + struct hid_report *report = report_enum->report_id_hash[j]; + if (report) + hid_free_report(report); +@@ -995,7 +999,12 @@ EXPORT_SYMBOL_GPL(hid_output_report); + + int hid_set_field(struct hid_field *field, unsigned offset, __s32 value) + { +- unsigned size = field->report_size; ++ unsigned size; ++ ++ if (!field) ++ return -1; ++ ++ size = field->report_size; + + hid_dump_input(field->report->device, field->usage + offset, value); + +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 14d22399..8cc08e23 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -595,6 +595,7 @@ + #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16 0x0012 + #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17 0x0013 + #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18 0x0014 ++#define USB_DEVICE_ID_NTRIG_DUOSENSE 0x1500 + + #define USB_VENDOR_ID_ONTRAK 0x0a07 + #define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 +diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c +index 21e473e7..f03c684e 100644 +--- a/drivers/hid/hid-input.c ++++ b/drivers/hid/hid-input.c +@@ -314,7 +314,7 @@ static int hidinput_get_battery_property(struct power_supply *psy, + { + struct hid_device *dev = container_of(psy, struct hid_device, battery); + int ret = 0; +- __u8 buf[2] = {}; ++ __u8 *buf; + + switch (prop) { + case POWER_SUPPLY_PROP_PRESENT: +@@ -323,13 +323,20 @@ static int hidinput_get_battery_property(struct power_supply *psy, + break; + + case POWER_SUPPLY_PROP_CAPACITY: ++ ++ buf = kmalloc(2 * sizeof(__u8), GFP_KERNEL); ++ if (!buf) { ++ ret = -ENOMEM; ++ break; ++ } + ret = dev->hid_get_raw_report(dev, dev->battery_report_id, +- buf, sizeof(buf), ++ buf, 2, + dev->battery_report_type); + + if (ret != 2) { + if (ret >= 0) + ret = -EINVAL; ++ kfree(buf); + break; + } + +@@ -338,6 +345,7 @@ static int hidinput_get_battery_property(struct power_supply *psy, + buf[1] <= dev->battery_max) + val->intval = (100 * (buf[1] - dev->battery_min)) / + (dev->battery_max - dev->battery_min); ++ kfree(buf); + break; + + case POWER_SUPPLY_PROP_MODEL_NAME: +diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c +index 9fae2ebd..48cba857 100644 +--- a/drivers/hid/hid-ntrig.c ++++ b/drivers/hid/hid-ntrig.c +@@ -115,7 +115,8 @@ static inline int ntrig_get_mode(struct hid_device *hdev) + struct hid_report *report = hdev->report_enum[HID_FEATURE_REPORT]. + report_id_hash[0x0d]; + +- if (!report) ++ if (!report || report->maxfield < 1 || ++ report->field[0]->report_count < 1) + return -EINVAL; + + usbhid_submit_report(hdev, report, USB_DIR_IN); +diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c +index 47ed74c4..00cd2f8b 100644 +--- a/drivers/hid/hid-pl.c ++++ b/drivers/hid/hid-pl.c +@@ -129,8 +129,14 @@ static int plff_init(struct hid_device *hid) + strong = &report->field[0]->value[2]; + weak = &report->field[0]->value[3]; + debug("detected single-field device"); +- } else if (report->maxfield >= 4 && report->field[0]->maxusage == 1 && +- report->field[0]->usage[0].hid == (HID_UP_LED | 0x43)) { ++ } else if (report->field[0]->maxusage == 1 && ++ report->field[0]->usage[0].hid == ++ (HID_UP_LED | 0x43) && ++ report->maxfield >= 4 && ++ report->field[0]->report_count >= 1 && ++ report->field[1]->report_count >= 1 && ++ report->field[2]->report_count >= 1 && ++ report->field[3]->report_count >= 1) { + report->field[0]->value[0] = 0x00; + report->field[1]->value[0] = 0x00; + strong = &report->field[2]->value[0]; +diff --git a/drivers/hid/hid-speedlink.c b/drivers/hid/hid-speedlink.c +index 60201374..2b03c9ba 100644 +--- a/drivers/hid/hid-speedlink.c ++++ b/drivers/hid/hid-speedlink.c +@@ -3,7 +3,7 @@ + * Fixes "jumpy" cursor and removes nonexistent keyboard LEDS from + * the HID descriptor. + * +- * Copyright (c) 2011 Stefan Kriwanek ++ * Copyright (c) 2011, 2013 Stefan Kriwanek + */ + + /* +@@ -48,8 +48,13 @@ static int speedlink_event(struct hid_device *hdev, struct hid_field *field, + struct hid_usage *usage, __s32 value) + { + /* No other conditions due to usage_table. */ +- /* Fix "jumpy" cursor (invalid events sent by device). */ +- if (value == 256) ++ ++ /* This fixes the "jumpy" cursor occuring due to invalid events sent ++ * by the device. Some devices only send them with value==+256, others ++ * don't. However, catching abs(value)>=256 is restrictive enough not ++ * to interfere with devices that were bug-free (has been tested). ++ */ ++ if (abs(value) >= 256) + return 1; + /* Drop useless distance 0 events (on button clicks etc.) as well */ + if (value == 0) +diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c +index 5c4112e6..d712294b 100644 +--- a/drivers/hid/usbhid/hid-quirks.c ++++ b/drivers/hid/usbhid/hid-quirks.c +@@ -103,6 +103,8 @@ static const struct hid_blacklist { + { USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS }, + { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X, HID_QUIRK_MULTI_INPUT }, + { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X, HID_QUIRK_MULTI_INPUT }, ++ { USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS }, ++ + { 0, 0 } + }; + +diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c +index 17119247..a60a54d8 100644 +--- a/drivers/iommu/intel-iommu.c ++++ b/drivers/iommu/intel-iommu.c +@@ -886,56 +886,54 @@ static int dma_pte_clear_range(struct dmar_domain *domain, + return order; + } + ++static void dma_pte_free_level(struct dmar_domain *domain, int level, ++ struct dma_pte *pte, unsigned long pfn, ++ unsigned long start_pfn, unsigned long last_pfn) ++{ ++ pfn = max(start_pfn, pfn); ++ pte = &pte[pfn_level_offset(pfn, level)]; ++ ++ do { ++ unsigned long level_pfn; ++ struct dma_pte *level_pte; ++ ++ if (!dma_pte_present(pte) || dma_pte_superpage(pte)) ++ goto next; ++ ++ level_pfn = pfn & level_mask(level - 1); ++ level_pte = phys_to_virt(dma_pte_addr(pte)); ++ ++ if (level > 2) ++ dma_pte_free_level(domain, level - 1, level_pte, ++ level_pfn, start_pfn, last_pfn); ++ ++ /* If range covers entire pagetable, free it */ ++ if (!(start_pfn > level_pfn || ++ last_pfn < level_pfn + level_size(level))) { ++ dma_clear_pte(pte); ++ domain_flush_cache(domain, pte, sizeof(*pte)); ++ free_pgtable_page(level_pte); ++ } ++next: ++ pfn += level_size(level); ++ } while (!first_pte_in_page(++pte) && pfn <= last_pfn); ++} ++ + /* free page table pages. last level pte should already be cleared */ + static void dma_pte_free_pagetable(struct dmar_domain *domain, + unsigned long start_pfn, + unsigned long last_pfn) + { + int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; +- struct dma_pte *first_pte, *pte; +- int total = agaw_to_level(domain->agaw); +- int level; +- unsigned long tmp; +- int large_page = 2; + + BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width); + BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width); + BUG_ON(start_pfn > last_pfn); + + /* We don't need lock here; nobody else touches the iova range */ +- level = 2; +- while (level <= total) { +- tmp = align_to_level(start_pfn, level); +- +- /* If we can't even clear one PTE at this level, we're done */ +- if (tmp + level_size(level) - 1 > last_pfn) +- return; +- +- do { +- large_page = level; +- first_pte = pte = dma_pfn_level_pte(domain, tmp, level, &large_page); +- if (large_page > level) +- level = large_page + 1; +- if (!pte) { +- tmp = align_to_level(tmp + 1, level + 1); +- continue; +- } +- do { +- if (dma_pte_present(pte)) { +- free_pgtable_page(phys_to_virt(dma_pte_addr(pte))); +- dma_clear_pte(pte); +- } +- pte++; +- tmp += level_size(level); +- } while (!first_pte_in_page(pte) && +- tmp + level_size(level) - 1 <= last_pfn); ++ dma_pte_free_level(domain, agaw_to_level(domain->agaw), ++ domain->pgd, 0, start_pfn, last_pfn); + +- domain_flush_cache(domain, first_pte, +- (void *)pte - (void *)first_pte); +- +- } while (tmp && tmp + level_size(level) - 1 <= last_pfn); +- level++; +- } + /* free pgd */ + if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) { + free_pgtable_page(domain->pgd); +diff --git a/drivers/mmc/host/tmio_mmc_dma.c b/drivers/mmc/host/tmio_mmc_dma.c +index fff92860..491e9ecc 100644 +--- a/drivers/mmc/host/tmio_mmc_dma.c ++++ b/drivers/mmc/host/tmio_mmc_dma.c +@@ -104,6 +104,7 @@ static void tmio_mmc_start_dma_rx(struct tmio_mmc_host *host) + pio: + if (!desc) { + /* DMA failed, fall back to PIO */ ++ tmio_mmc_enable_dma(host, false); + if (ret >= 0) + ret = -EIO; + host->chan_rx = NULL; +@@ -116,7 +117,6 @@ pio: + } + dev_warn(&host->pdev->dev, + "DMA failed: %d, falling back to PIO\n", ret); +- tmio_mmc_enable_dma(host, false); + } + + dev_dbg(&host->pdev->dev, "%s(): desc %p, cookie %d, sg[%d]\n", __func__, +@@ -185,6 +185,7 @@ static void tmio_mmc_start_dma_tx(struct tmio_mmc_host *host) + pio: + if (!desc) { + /* DMA failed, fall back to PIO */ ++ tmio_mmc_enable_dma(host, false); + if (ret >= 0) + ret = -EIO; + host->chan_tx = NULL; +@@ -197,7 +198,6 @@ pio: + } + dev_warn(&host->pdev->dev, + "DMA failed: %d, falling back to PIO\n", ret); +- tmio_mmc_enable_dma(host, false); + } + + dev_dbg(&host->pdev->dev, "%s(): desc %p, cookie %d\n", __func__, +diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c +index f86ee0c7..503ff9f6 100644 +--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c +@@ -1030,6 +1030,10 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, + * is_on == 0 means MRC CCK is OFF (more noise imm) + */ + bool is_on = param ? 1 : 0; ++ ++ if (ah->caps.rx_chainmask == 1) ++ break; ++ + REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL, + AR_PHY_MRC_CCK_ENABLE, is_on); + REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL, +diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h +index 4bfb44a0..e2ab182d 100644 +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -78,10 +78,6 @@ struct ath_config { + sizeof(struct ath_buf_state)); \ + } while (0) + +-#define ATH_RXBUF_RESET(_bf) do { \ +- (_bf)->bf_stale = false; \ +- } while (0) +- + /** + * enum buffer_type - Buffer type flags + * +@@ -314,6 +310,7 @@ struct ath_rx { + struct ath_buf *rx_bufptr; + struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX]; + ++ struct ath_buf *buf_hold; + struct sk_buff *frag; + }; + +diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c +index 039bac7e..2e6583d3 100644 +--- a/drivers/net/wireless/ath/ath9k/recv.c ++++ b/drivers/net/wireless/ath/ath9k/recv.c +@@ -78,8 +78,6 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) + struct ath_desc *ds; + struct sk_buff *skb; + +- ATH_RXBUF_RESET(bf); +- + ds = bf->bf_desc; + ds->ds_link = 0; /* link to null */ + ds->ds_data = bf->bf_buf_addr; +@@ -106,6 +104,14 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) + sc->rx.rxlink = &ds->ds_link; + } + ++static void ath_rx_buf_relink(struct ath_softc *sc, struct ath_buf *bf) ++{ ++ if (sc->rx.buf_hold) ++ ath_rx_buf_link(sc, sc->rx.buf_hold); ++ ++ sc->rx.buf_hold = bf; ++} ++ + static void ath_setdefantenna(struct ath_softc *sc, u32 antenna) + { + /* XXX block beacon interrupts */ +@@ -153,7 +159,6 @@ static bool ath_rx_edma_buf_link(struct ath_softc *sc, + + skb = bf->bf_mpdu; + +- ATH_RXBUF_RESET(bf); + memset(skb->data, 0, ah->caps.rx_status_len); + dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, + ah->caps.rx_status_len, DMA_TO_DEVICE); +@@ -485,6 +490,7 @@ int ath_startrecv(struct ath_softc *sc) + if (list_empty(&sc->rx.rxbuf)) + goto start_recv; + ++ sc->rx.buf_hold = NULL; + sc->rx.rxlink = NULL; + list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) { + ath_rx_buf_link(sc, bf); +@@ -734,6 +740,9 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc, + } + + bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list); ++ if (bf == sc->rx.buf_hold) ++ return NULL; ++ + ds = bf->bf_desc; + + /* +@@ -1974,7 +1983,7 @@ requeue: + if (edma) { + ath_rx_edma_buf_link(sc, qtype); + } else { +- ath_rx_buf_link(sc, bf); ++ ath_rx_buf_relink(sc, bf); + ath9k_hw_rxena(ah); + } + } while (1); +diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c +index 12a42f2c..3d0aa472 100644 +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -2479,6 +2479,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) + for (acno = 0, ac = &an->ac[acno]; + acno < WME_NUM_AC; acno++, ac++) { + ac->sched = false; ++ ac->clear_ps_filter = true; + ac->txq = sc->tx.txq_map[acno]; + INIT_LIST_HEAD(&ac->tid_q); + } +diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c +index 11054ae9..9a184058 100644 +--- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c +@@ -1013,9 +1013,10 @@ static bool dma64_rxidle(struct dma_info *di) + + /* + * post receive buffers +- * return false is refill failed completely and ring is empty this will stall +- * the rx dma and user might want to call rxfill again asap. This unlikely +- * happens on memory-rich NIC, but often on memory-constrained dongle ++ * Return false if refill failed completely or dma mapping failed. The ring ++ * is empty, which will stall the rx dma and user might want to call rxfill ++ * again asap. This is unlikely to happen on a memory-rich NIC, but often on ++ * memory-constrained dongle. + */ + bool dma_rxfill(struct dma_pub *pub) + { +@@ -1074,6 +1075,8 @@ bool dma_rxfill(struct dma_pub *pub) + + pa = dma_map_single(di->dmadev, p->data, di->rxbufsize, + DMA_FROM_DEVICE); ++ if (dma_mapping_error(di->dmadev, pa)) ++ return false; + + /* save the free packet pointer */ + di->rxp[rxout] = p; +@@ -1294,7 +1297,11 @@ int dma_txfast(struct dma_pub *pub, struct sk_buff *p, bool commit) + + /* get physical address of buffer start */ + pa = dma_map_single(di->dmadev, data, len, DMA_TO_DEVICE); +- ++ /* if mapping failed, free skb */ ++ if (dma_mapping_error(di->dmadev, pa)) { ++ brcmu_pkt_buf_free_skb(p); ++ return; ++ } + /* With a DMA segment list, Descriptor table is filled + * using the segment list instead of looping over + * buffers in multi-chain DMA. Therefore, EOF for SGLIST +diff --git a/drivers/of/base.c b/drivers/of/base.c +index 58064498..1c207f23 100644 +--- a/drivers/of/base.c ++++ b/drivers/of/base.c +@@ -1227,6 +1227,7 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align)) + ap = dt_alloc(sizeof(*ap) + len + 1, 4); + if (!ap) + continue; ++ memset(ap, 0, sizeof(*ap) + len + 1); + ap->alias = start; + of_alias_add(ap, np, id, start, len); + } +diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c +index 105fff2e..05973a49 100644 +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -2225,14 +2225,9 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) + } + } + +- if (modepage == 0x3F) { +- sd_printk(KERN_ERR, sdkp, "No Caching mode page " +- "present\n"); +- goto defaults; +- } else if ((buffer[offset] & 0x3f) != modepage) { +- sd_printk(KERN_ERR, sdkp, "Got wrong page\n"); +- goto defaults; +- } ++ sd_printk(KERN_ERR, sdkp, "No Caching mode page found\n"); ++ goto defaults; ++ + Page_found: + if (modepage == 8) { + sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0); +diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c +index 95ebc267..e3adb382 100644 +--- a/drivers/staging/comedi/drivers/dt282x.c ++++ b/drivers/staging/comedi/drivers/dt282x.c +@@ -407,8 +407,9 @@ struct dt282x_private { + } \ + udelay(5); \ + } \ +- if (_i) \ ++ if (_i) { \ + b \ ++ } \ + } while (0) + + static int dt282x_attach(struct comedi_device *dev, +diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c +index 9dd51f7f..1434ee9e 100644 +--- a/drivers/usb/class/cdc-wdm.c ++++ b/drivers/usb/class/cdc-wdm.c +@@ -233,6 +233,7 @@ skip_error: + static void wdm_int_callback(struct urb *urb) + { + int rv = 0; ++ int responding; + int status = urb->status; + struct wdm_device *desc; + struct usb_cdc_notification *dr; +@@ -286,8 +287,8 @@ static void wdm_int_callback(struct urb *urb) + + spin_lock(&desc->iuspin); + clear_bit(WDM_READ, &desc->flags); +- set_bit(WDM_RESPONDING, &desc->flags); +- if (!test_bit(WDM_DISCONNECTING, &desc->flags) ++ responding = test_and_set_bit(WDM_RESPONDING, &desc->flags); ++ if (!responding && !test_bit(WDM_DISCONNECTING, &desc->flags) + && !test_bit(WDM_SUSPENDING, &desc->flags)) { + rv = usb_submit_urb(desc->response, GFP_ATOMIC); + dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", +@@ -687,16 +688,20 @@ static void wdm_rxwork(struct work_struct *work) + { + struct wdm_device *desc = container_of(work, struct wdm_device, rxwork); + unsigned long flags; +- int rv; ++ int rv = 0; ++ int responding; + + spin_lock_irqsave(&desc->iuspin, flags); + if (test_bit(WDM_DISCONNECTING, &desc->flags)) { + spin_unlock_irqrestore(&desc->iuspin, flags); + } else { ++ responding = test_and_set_bit(WDM_RESPONDING, &desc->flags); + spin_unlock_irqrestore(&desc->iuspin, flags); +- rv = usb_submit_urb(desc->response, GFP_KERNEL); ++ if (!responding) ++ rv = usb_submit_urb(desc->response, GFP_KERNEL); + if (rv < 0 && rv != -EPERM) { + spin_lock_irqsave(&desc->iuspin, flags); ++ clear_bit(WDM_RESPONDING, &desc->flags); + if (!test_bit(WDM_DISCONNECTING, &desc->flags)) + schedule_work(&desc->rxwork); + spin_unlock_irqrestore(&desc->iuspin, flags); +diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c +index f4bdd0ce..78609d30 100644 +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -424,7 +424,8 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, + + memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE); + if (config->desc.bDescriptorType != USB_DT_CONFIG || +- config->desc.bLength < USB_DT_CONFIG_SIZE) { ++ config->desc.bLength < USB_DT_CONFIG_SIZE || ++ config->desc.bLength > size) { + dev_err(ddev, "invalid descriptor for config index %d: " + "type = 0x%X, length = %d\n", cfgidx, + config->desc.bDescriptorType, config->desc.bLength); +diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c +index a797d51e..77477ca5 100644 +--- a/drivers/usb/host/ehci-mxc.c ++++ b/drivers/usb/host/ehci-mxc.c +@@ -298,7 +298,7 @@ static int __exit ehci_mxc_drv_remove(struct platform_device *pdev) + if (pdata && pdata->exit) + pdata->exit(pdev); + +- if (pdata->otg) ++ if (pdata && pdata->otg) + usb_phy_shutdown(pdata->otg); + + usb_remove_hcd(hcd); +diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c +index 93ad67ec..6e70ce97 100644 +--- a/drivers/usb/host/xhci-plat.c ++++ b/drivers/usb/host/xhci-plat.c +@@ -24,7 +24,7 @@ static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci) + * here that the generic code does not try to make a pci_dev from our + * dev struct in order to setup MSI + */ +- xhci->quirks |= XHCI_BROKEN_MSI; ++ xhci->quirks |= XHCI_PLAT; + } + + /* called during probe() after chip reset completes */ +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 8072a932..1504946c 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -342,9 +342,14 @@ static void xhci_msix_sync_irqs(struct xhci_hcd *xhci) + static int xhci_try_enable_msi(struct usb_hcd *hcd) + { + struct xhci_hcd *xhci = hcd_to_xhci(hcd); +- struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); ++ struct pci_dev *pdev; + int ret; + ++ /* The xhci platform device has set up IRQs through usb_add_hcd. */ ++ if (xhci->quirks & XHCI_PLAT) ++ return 0; ++ ++ pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); + /* + * Some Fresco Logic host controllers advertise MSI, but fail to + * generate interrupts. Don't even try to enable MSI. +@@ -3496,10 +3501,21 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) + { + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct xhci_virt_device *virt_dev; ++ struct device *dev = hcd->self.controller; + unsigned long flags; + u32 state; + int i, ret; + ++#ifndef CONFIG_USB_DEFAULT_PERSIST ++ /* ++ * We called pm_runtime_get_noresume when the device was attached. ++ * Decrement the counter here to allow controller to runtime suspend ++ * if no devices remain. ++ */ ++ if (xhci->quirks & XHCI_RESET_ON_RESUME) ++ pm_runtime_put_noidle(dev); ++#endif ++ + ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__); + /* If the host is halted due to driver unload, we still need to free the + * device. +@@ -3571,6 +3587,7 @@ static int xhci_reserve_host_control_ep_resources(struct xhci_hcd *xhci) + int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) + { + struct xhci_hcd *xhci = hcd_to_xhci(hcd); ++ struct device *dev = hcd->self.controller; + unsigned long flags; + int timeleft; + int ret; +@@ -3623,6 +3640,16 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) + goto disable_slot; + } + udev->slot_id = xhci->slot_id; ++ ++#ifndef CONFIG_USB_DEFAULT_PERSIST ++ /* ++ * If resetting upon resume, we can't put the controller into runtime ++ * suspend if there is a device attached. ++ */ ++ if (xhci->quirks & XHCI_RESET_ON_RESUME) ++ pm_runtime_get_noresume(dev); ++#endif ++ + /* Is this a LS or FS device under a HS hub? */ + /* Hub or peripherial? */ + return 1; +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index 15aaf58c..a54a408c 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1508,6 +1508,7 @@ struct xhci_hcd { + #define XHCI_SPURIOUS_REBOOT (1 << 13) + #define XHCI_COMP_MODE_QUIRK (1 << 14) + #define XHCI_AVOID_BEI (1 << 15) ++#define XHCI_PLAT (1 << 16) + unsigned int num_active_eps; + unsigned int limit_active_eps; + /* There are two roothubs to keep track of bus suspend info for */ +diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c +index cdde45de..4491830b 100644 +--- a/drivers/usb/serial/mos7720.c ++++ b/drivers/usb/serial/mos7720.c +@@ -383,7 +383,7 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport, + kfree(urbtrack); + return -ENOMEM; + } +- urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_KERNEL); ++ urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_ATOMIC); + if (!urbtrack->setup) { + usb_free_urb(urbtrack->urb); + kfree(urbtrack); +@@ -391,8 +391,8 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport, + } + urbtrack->setup->bRequestType = (__u8)0x40; + urbtrack->setup->bRequest = (__u8)0x0e; +- urbtrack->setup->wValue = get_reg_value(reg, dummy); +- urbtrack->setup->wIndex = get_reg_index(reg); ++ urbtrack->setup->wValue = cpu_to_le16(get_reg_value(reg, dummy)); ++ urbtrack->setup->wIndex = cpu_to_le16(get_reg_index(reg)); + urbtrack->setup->wLength = 0; + usb_fill_control_urb(urbtrack->urb, usbdev, + usb_sndctrlpipe(usbdev, 0), +diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c +index 7e34beed..3275bde6 100644 +--- a/drivers/xen/grant-table.c ++++ b/drivers/xen/grant-table.c +@@ -641,9 +641,18 @@ void gnttab_request_free_callback(struct gnttab_free_callback *callback, + void (*fn)(void *), void *arg, u16 count) + { + unsigned long flags; ++ struct gnttab_free_callback *cb; ++ + spin_lock_irqsave(&gnttab_list_lock, flags); +- if (callback->next) +- goto out; ++ ++ /* Check if the callback is already on the list */ ++ cb = gnttab_free_callback_list; ++ while (cb) { ++ if (cb == callback) ++ goto out; ++ cb = cb->next; ++ } ++ + callback->fn = fn; + callback->arg = arg; + callback->count = count; +diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c +index e7fe81d3..4ac06b08 100644 +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -362,6 +362,7 @@ cifs_reconnect(struct TCP_Server_Info *server) + try_to_freeze(); + + /* we should try only the port we connected to before */ ++ mutex_lock(&server->srv_mutex); + rc = generic_ip_connect(server); + if (rc) { + cFYI(1, "reconnect error %d", rc); +@@ -373,6 +374,7 @@ cifs_reconnect(struct TCP_Server_Info *server) + server->tcpStatus = CifsNeedNegotiate; + spin_unlock(&GlobalMid_Lock); + } ++ mutex_unlock(&server->srv_mutex); + } while (server->tcpStatus == CifsNeedReconnect); + + return rc; +diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c +index d48478a8..373b2514 100644 +--- a/fs/fuse/dir.c ++++ b/fs/fuse/dir.c +@@ -1503,6 +1503,8 @@ static int fuse_setxattr(struct dentry *entry, const char *name, + fc->no_setxattr = 1; + err = -EOPNOTSUPP; + } ++ if (!err) ++ fuse_invalidate_attr(inode); + return err; + } + +@@ -1632,6 +1634,8 @@ static int fuse_removexattr(struct dentry *entry, const char *name) + fc->no_removexattr = 1; + err = -EOPNOTSUPP; + } ++ if (!err) ++ fuse_invalidate_attr(inode); + return err; + } + +diff --git a/fs/fuse/file.c b/fs/fuse/file.c +index 8e6381a1..df25454e 100644 +--- a/fs/fuse/file.c ++++ b/fs/fuse/file.c +@@ -1294,7 +1294,6 @@ static int fuse_writepage_locked(struct page *page) + + inc_bdi_stat(mapping->backing_dev_info, BDI_WRITEBACK); + inc_zone_page_state(tmp_page, NR_WRITEBACK_TEMP); +- end_page_writeback(page); + + spin_lock(&fc->lock); + list_add(&req->writepages_entry, &fi->writepages); +@@ -1302,6 +1301,8 @@ static int fuse_writepage_locked(struct page *page) + fuse_flush_writepages(inode); + spin_unlock(&fc->lock); + ++ end_page_writeback(page); ++ + return 0; + + err_free: +diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c +index 29037c36..e92a342f 100644 +--- a/fs/isofs/inode.c ++++ b/fs/isofs/inode.c +@@ -119,8 +119,8 @@ static void destroy_inodecache(void) + + static int isofs_remount(struct super_block *sb, int *flags, char *data) + { +- /* we probably want a lot more here */ +- *flags |= MS_RDONLY; ++ if (!(*flags & MS_RDONLY)) ++ return -EROFS; + return 0; + } + +@@ -769,15 +769,6 @@ root_found: + */ + s->s_maxbytes = 0x80000000000LL; + +- /* +- * The CDROM is read-only, has no nodes (devices) on it, and since +- * all of the files appear to be owned by root, we really do not want +- * to allow suid. (suid or devices will not show up unless we have +- * Rock Ridge extensions) +- */ +- +- s->s_flags |= MS_RDONLY /* | MS_NODEV | MS_NOSUID */; +- + /* Set this for reference. Its not currently used except on write + which we don't have .. */ + +@@ -1536,6 +1527,9 @@ struct inode *isofs_iget(struct super_block *sb, + static struct dentry *isofs_mount(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data) + { ++ /* We don't support read-write mounts */ ++ if (!(flags & MS_RDONLY)) ++ return ERR_PTR(-EACCES); + return mount_bdev(fs_type, flags, dev_name, data, isofs_fill_super); + } + +diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c +index 7eb1c0c7..cf228479 100644 +--- a/fs/ocfs2/extent_map.c ++++ b/fs/ocfs2/extent_map.c +@@ -782,7 +782,6 @@ int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, + cpos = map_start >> osb->s_clustersize_bits; + mapping_end = ocfs2_clusters_for_bytes(inode->i_sb, + map_start + map_len); +- mapping_end -= cpos; + is_last = 0; + while (cpos < mapping_end && !is_last) { + u32 fe_flags; +diff --git a/include/linux/hid.h b/include/linux/hid.h +index 3a95da60..8c933a86 100644 +--- a/include/linux/hid.h ++++ b/include/linux/hid.h +@@ -420,10 +420,12 @@ struct hid_report { + struct hid_device *device; /* associated device */ + }; + ++#define HID_MAX_IDS 256 ++ + struct hid_report_enum { + unsigned numbered; + struct list_head report_list; +- struct hid_report *report_id_hash[256]; ++ struct hid_report *report_id_hash[HID_MAX_IDS]; + }; + + #define HID_REPORT_TYPES 3 +diff --git a/include/linux/rculist.h b/include/linux/rculist.h +index 6f95e241..38633526 100644 +--- a/include/linux/rculist.h ++++ b/include/linux/rculist.h +@@ -254,8 +254,9 @@ static inline void list_splice_init_rcu(struct list_head *list, + */ + #define list_first_or_null_rcu(ptr, type, member) \ + ({struct list_head *__ptr = (ptr); \ +- struct list_head __rcu *__next = list_next_rcu(__ptr); \ +- likely(__ptr != __next) ? container_of(__next, type, member) : NULL; \ ++ struct list_head *__next = ACCESS_ONCE(__ptr->next); \ ++ likely(__ptr != __next) ? \ ++ list_entry_rcu(__next, type, member) : NULL; \ + }) + + /** +diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h +index 11e67562..ab45ea5b 100644 +--- a/include/media/v4l2-ctrls.h ++++ b/include/media/v4l2-ctrls.h +@@ -22,6 +22,7 @@ + #define _V4L2_CTRLS_H + + #include ++#include + #include + + /* forward references */ +diff --git a/mm/huge_memory.c b/mm/huge_memory.c +index ef99c15f..3da5c0bf 100644 +--- a/mm/huge_memory.c ++++ b/mm/huge_memory.c +@@ -1894,6 +1894,8 @@ static void collapse_huge_page(struct mm_struct *mm, + goto out; + + vma = find_vma(mm, address); ++ if (!vma) ++ goto out; + hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK; + hend = vma->vm_end & HPAGE_PMD_MASK; + if (address < hstart || address + HPAGE_PMD_SIZE > hend) +diff --git a/mm/memcontrol.c b/mm/memcontrol.c +index 81c275b3..9c364428 100644 +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -4349,7 +4349,13 @@ static int compare_thresholds(const void *a, const void *b) + const struct mem_cgroup_threshold *_a = a; + const struct mem_cgroup_threshold *_b = b; + +- return _a->threshold - _b->threshold; ++ if (_a->threshold > _b->threshold) ++ return 1; ++ ++ if (_a->threshold < _b->threshold) ++ return -1; ++ ++ return 0; + } + + static int mem_cgroup_oom_notify_cb(struct mem_cgroup *memcg) +diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c +index 1f350522..e6083c14 100644 +--- a/sound/pci/hda/hda_intel.c ++++ b/sound/pci/hda/hda_intel.c +@@ -2602,6 +2602,7 @@ static struct snd_pci_quirk msi_black_list[] __devinitdata = { + SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */ + SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */ + SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */ ++ SND_PCI_QUIRK(0x1179, 0xfb44, "Toshiba Satellite C870", 0), /* AMD Hudson */ + SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */ + SND_PCI_QUIRK(0xa0a0, 0x0575, "Aopen MZ915-M", 0), /* ICH6 */ + {} +diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c +index 840d7208..ddb0d904 100644 +--- a/sound/soc/codecs/wm8960.c ++++ b/sound/soc/codecs/wm8960.c +@@ -790,9 +790,9 @@ static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, + if (pll_div.k) { + reg |= 0x20; + +- snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 18) & 0x3f); +- snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 9) & 0x1ff); +- snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0x1ff); ++ snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 16) & 0xff); ++ snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 8) & 0xff); ++ snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0xff); + } + snd_soc_write(codec, WM8960_PLL1, reg); + diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.63-64.patch b/patch/kernel/sun8i-default/0001-patch-3.4.63-64.patch new file mode 100644 index 000000000..d486e6f85 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.63-64.patch @@ -0,0 +1,681 @@ +diff --git a/Makefile b/Makefile +index 94ce941..580b364 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 63 ++SUBLEVEL = 64 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c +index 505f27e..8d1724c 100644 +--- a/drivers/gpu/drm/radeon/atombios_dp.c ++++ b/drivers/gpu/drm/radeon/atombios_dp.c +@@ -51,7 +51,7 @@ static char *pre_emph_names[] = { + * or from atom. Note that atom operates on + * dw units. + */ +-static void radeon_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le) ++void radeon_atom_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le) + { + #ifdef __BIG_ENDIAN + u8 src_tmp[20], dst_tmp[20]; /* used for byteswapping */ +@@ -101,7 +101,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan, + + base = (unsigned char *)(rdev->mode_info.atom_context->scratch + 1); + +- radeon_copy_swap(base, send, send_bytes, true); ++ radeon_atom_copy_swap(base, send, send_bytes, true); + + args.v1.lpAuxRequest = cpu_to_le16((u16)(0 + 4)); + args.v1.lpDataOut = cpu_to_le16((u16)(16 + 4)); +@@ -138,7 +138,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan, + recv_bytes = recv_size; + + if (recv && recv_size) +- radeon_copy_swap(recv, base + 16, recv_bytes, false); ++ radeon_atom_copy_swap(recv, base + 16, recv_bytes, false); + + return recv_bytes; + } +diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c +index ced9370..2f755e2 100644 +--- a/drivers/gpu/drm/radeon/atombios_encoders.c ++++ b/drivers/gpu/drm/radeon/atombios_encoders.c +@@ -1425,8 +1425,12 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) + atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); +- /* some early dce3.2 boards have a bug in their transmitter control table */ +- if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730)) ++ /* some dce3.x boards have a bug in their transmitter control table. ++ * ACTION_ENABLE_OUTPUT can probably be dropped since ACTION_ENABLE ++ * does the same thing and more. ++ */ ++ if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730) && ++ (rdev->family != CHIP_RS880)) + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); + } + if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { +diff --git a/drivers/gpu/drm/radeon/atombios_i2c.c b/drivers/gpu/drm/radeon/atombios_i2c.c +index 44d87b6..9ed94a8 100644 +--- a/drivers/gpu/drm/radeon/atombios_i2c.c ++++ b/drivers/gpu/drm/radeon/atombios_i2c.c +@@ -27,6 +27,8 @@ + #include "radeon.h" + #include "atom.h" + ++extern void radeon_atom_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le); ++ + #define TARGET_HW_I2C_CLOCK 50 + + /* these are a limitation of ProcessI2cChannelTransaction not the hw */ +@@ -77,7 +79,7 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan, + } + + if (!(flags & HW_I2C_WRITE)) +- memcpy(buf, base, num); ++ radeon_atom_copy_swap(buf, base, num, false); + + return 0; + } +diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c +index 300099d..15d1f08 100644 +--- a/drivers/gpu/drm/radeon/evergreen.c ++++ b/drivers/gpu/drm/radeon/evergreen.c +@@ -534,7 +534,8 @@ static u32 evergreen_line_buffer_adjust(struct radeon_device *rdev, + struct drm_display_mode *mode, + struct drm_display_mode *other_mode) + { +- u32 tmp; ++ u32 tmp, buffer_alloc, i; ++ u32 pipe_offset = radeon_crtc->crtc_id * 0x20; + /* + * Line Buffer Setup + * There are 3 line buffers, each one shared by 2 display controllers. +@@ -557,18 +558,34 @@ static u32 evergreen_line_buffer_adjust(struct radeon_device *rdev, + * non-linked crtcs for maximum line buffer allocation. + */ + if (radeon_crtc->base.enabled && mode) { +- if (other_mode) ++ if (other_mode) { + tmp = 0; /* 1/2 */ +- else ++ buffer_alloc = 1; ++ } else { + tmp = 2; /* whole */ +- } else ++ buffer_alloc = 2; ++ } ++ } else { + tmp = 0; ++ buffer_alloc = 0; ++ } + + /* second controller of the pair uses second half of the lb */ + if (radeon_crtc->crtc_id % 2) + tmp += 4; + WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset, tmp); + ++ if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { ++ WREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset, ++ DMIF_BUFFERS_ALLOCATED(buffer_alloc)); ++ for (i = 0; i < rdev->usec_timeout; i++) { ++ if (RREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset) & ++ DMIF_BUFFERS_ALLOCATED_COMPLETED) ++ break; ++ udelay(1); ++ } ++ } ++ + if (radeon_crtc->base.enabled && mode) { + switch (tmp) { + case 0: +diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h +index 81e744f..52aabf2 100644 +--- a/drivers/gpu/drm/radeon/evergreend.h ++++ b/drivers/gpu/drm/radeon/evergreend.h +@@ -472,6 +472,10 @@ + # define LATENCY_LOW_WATERMARK(x) ((x) << 0) + # define LATENCY_HIGH_WATERMARK(x) ((x) << 16) + ++#define PIPE0_DMIF_BUFFER_CONTROL 0x0ca0 ++# define DMIF_BUFFERS_ALLOCATED(x) ((x) << 0) ++# define DMIF_BUFFERS_ALLOCATED_COMPLETED (1 << 4) ++ + #define IH_RB_CNTL 0x3e00 + # define IH_RB_ENABLE (1 << 0) + # define IH_IB_SIZE(x) ((x) << 1) /* log2 */ +diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c +index 38d87e1..c54d295 100644 +--- a/drivers/gpu/drm/radeon/radeon_atombios.c ++++ b/drivers/gpu/drm/radeon/radeon_atombios.c +@@ -715,13 +715,16 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) + (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *) + (ctx->bios + data_offset + + le16_to_cpu(router_obj->asObjects[k].usSrcDstTableOffset)); ++ u8 *num_dst_objs = (u8 *) ++ ((u8 *)router_src_dst_table + 1 + ++ (router_src_dst_table->ucNumberOfSrc * 2)); ++ u16 *dst_objs = (u16 *)(num_dst_objs + 1); + int enum_id; + + router.router_id = router_obj_id; +- for (enum_id = 0; enum_id < router_src_dst_table->ucNumberOfDst; +- enum_id++) { ++ for (enum_id = 0; enum_id < (*num_dst_objs); enum_id++) { + if (le16_to_cpu(path->usConnObjectId) == +- le16_to_cpu(router_src_dst_table->usDstObjectID[enum_id])) ++ le16_to_cpu(dst_objs[enum_id])) + break; + } + +@@ -1622,7 +1625,9 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct + kfree(edid); + } + } +- record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD); ++ record += fake_edid_record->ucFakeEDIDLength ? ++ fake_edid_record->ucFakeEDIDLength + 2 : ++ sizeof(ATOM_FAKE_EDID_PATCH_RECORD); + break; + case LCD_PANEL_RESOLUTION_RECORD_TYPE: + panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record; +diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c +index 5099bd3..b367d1d 100644 +--- a/drivers/gpu/drm/radeon/rs400.c ++++ b/drivers/gpu/drm/radeon/rs400.c +@@ -174,10 +174,13 @@ int rs400_gart_enable(struct radeon_device *rdev) + /* FIXME: according to doc we should set HIDE_MMCFG_BAR=0, + * AGPMODE30=0 & AGP30ENHANCED=0 in NB_CNTL */ + if ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740)) { +- WREG32_MC(RS480_MC_MISC_CNTL, +- (RS480_GART_INDEX_REG_EN | RS690_BLOCK_GFX_D3_EN)); ++ tmp = RREG32_MC(RS480_MC_MISC_CNTL); ++ tmp |= RS480_GART_INDEX_REG_EN | RS690_BLOCK_GFX_D3_EN; ++ WREG32_MC(RS480_MC_MISC_CNTL, tmp); + } else { +- WREG32_MC(RS480_MC_MISC_CNTL, RS480_GART_INDEX_REG_EN); ++ tmp = RREG32_MC(RS480_MC_MISC_CNTL); ++ tmp |= RS480_GART_INDEX_REG_EN; ++ WREG32_MC(RS480_MC_MISC_CNTL, tmp); + } + /* Enable gart */ + WREG32_MC(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN | size_reg)); +diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c +index e22b460..bd1f18c 100644 +--- a/drivers/gpu/drm/radeon/si.c ++++ b/drivers/gpu/drm/radeon/si.c +@@ -411,7 +411,8 @@ static u32 dce6_line_buffer_adjust(struct radeon_device *rdev, + struct drm_display_mode *mode, + struct drm_display_mode *other_mode) + { +- u32 tmp; ++ u32 tmp, buffer_alloc, i; ++ u32 pipe_offset = radeon_crtc->crtc_id * 0x20; + /* + * Line Buffer Setup + * There are 3 line buffers, each one shared by 2 display controllers. +@@ -426,16 +427,30 @@ static u32 dce6_line_buffer_adjust(struct radeon_device *rdev, + * non-linked crtcs for maximum line buffer allocation. + */ + if (radeon_crtc->base.enabled && mode) { +- if (other_mode) ++ if (other_mode) { + tmp = 0; /* 1/2 */ +- else ++ buffer_alloc = 1; ++ } else { + tmp = 2; /* whole */ +- } else ++ buffer_alloc = 2; ++ } ++ } else { + tmp = 0; ++ buffer_alloc = 0; ++ } + + WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset, + DC_LB_MEMORY_CONFIG(tmp)); + ++ WREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset, ++ DMIF_BUFFERS_ALLOCATED(buffer_alloc)); ++ for (i = 0; i < rdev->usec_timeout; i++) { ++ if (RREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset) & ++ DMIF_BUFFERS_ALLOCATED_COMPLETED) ++ break; ++ udelay(1); ++ } ++ + if (radeon_crtc->base.enabled && mode) { + switch (tmp) { + case 0: +diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h +index 45e240d..1767ae7 100644 +--- a/drivers/gpu/drm/radeon/sid.h ++++ b/drivers/gpu/drm/radeon/sid.h +@@ -57,6 +57,10 @@ + + #define DMIF_ADDR_CALC 0xC00 + ++#define PIPE0_DMIF_BUFFER_CONTROL 0x0ca0 ++# define DMIF_BUFFERS_ALLOCATED(x) ((x) << 0) ++# define DMIF_BUFFERS_ALLOCATED_COMPLETED (1 << 4) ++ + #define SRBM_STATUS 0xE50 + + #define CC_SYS_RB_BACKEND_DISABLE 0xe80 +diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c +index fa09daf..ea10bbe 100644 +--- a/drivers/gpu/drm/ttm/ttm_tt.c ++++ b/drivers/gpu/drm/ttm/ttm_tt.c +@@ -170,7 +170,7 @@ void ttm_tt_destroy(struct ttm_tt *ttm) + ttm_tt_unbind(ttm); + } + +- if (likely(ttm->pages != NULL)) { ++ if (ttm->state == tt_unbound) { + ttm->bdev->driver->ttm_tt_unpopulate(ttm); + } + +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index ab59fdf..e937a58 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -821,6 +821,64 @@ static int search(__s32 *array, __s32 value, unsigned n) + return -1; + } + ++static const char * const hid_report_names[] = { ++ "HID_INPUT_REPORT", ++ "HID_OUTPUT_REPORT", ++ "HID_FEATURE_REPORT", ++}; ++/** ++ * hid_validate_values - validate existing device report's value indexes ++ * ++ * @device: hid device ++ * @type: which report type to examine ++ * @id: which report ID to examine (0 for first) ++ * @field_index: which report field to examine ++ * @report_counts: expected number of values ++ * ++ * Validate the number of values in a given field of a given report, after ++ * parsing. ++ */ ++struct hid_report *hid_validate_values(struct hid_device *hid, ++ unsigned int type, unsigned int id, ++ unsigned int field_index, ++ unsigned int report_counts) ++{ ++ struct hid_report *report; ++ ++ if (type > HID_FEATURE_REPORT) { ++ hid_err(hid, "invalid HID report type %u\n", type); ++ return NULL; ++ } ++ ++ if (id >= HID_MAX_IDS) { ++ hid_err(hid, "invalid HID report id %u\n", id); ++ return NULL; ++ } ++ ++ /* ++ * Explicitly not using hid_get_report() here since it depends on ++ * ->numbered being checked, which may not always be the case when ++ * drivers go to access report values. ++ */ ++ report = hid->report_enum[type].report_id_hash[id]; ++ if (!report) { ++ hid_err(hid, "missing %s %u\n", hid_report_names[type], id); ++ return NULL; ++ } ++ if (report->maxfield <= field_index) { ++ hid_err(hid, "not enough fields in %s %u\n", ++ hid_report_names[type], id); ++ return NULL; ++ } ++ if (report->field[field_index]->report_count < report_counts) { ++ hid_err(hid, "not enough values in %s %u field %u\n", ++ hid_report_names[type], id, field_index); ++ return NULL; ++ } ++ return report; ++} ++EXPORT_SYMBOL_GPL(hid_validate_values); ++ + /** + * hid_match_report - check if driver's raw_event should be called + * +diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c +index 73b67ab..2652846 100644 +--- a/drivers/hid/hid-logitech-dj.c ++++ b/drivers/hid/hid-logitech-dj.c +@@ -454,7 +454,7 @@ static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev, + struct hid_report *report; + struct hid_report_enum *output_report_enum; + u8 *data = (u8 *)(&dj_report->device_index); +- int i; ++ unsigned int i; + + output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT]; + report = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT]; +@@ -464,7 +464,7 @@ static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev, + return -ENODEV; + } + +- for (i = 0; i < report->field[0]->report_count; i++) ++ for (i = 0; i < DJREPORT_SHORT_LENGTH - 1; i++) + report->field[0]->value[i] = data[i]; + + usbhid_submit_report(hdev, report, USB_DIR_OUT); +@@ -783,6 +783,12 @@ static int logi_dj_probe(struct hid_device *hdev, + goto hid_parse_fail; + } + ++ if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, REPORT_ID_DJ_SHORT, ++ 0, DJREPORT_SHORT_LENGTH - 1)) { ++ retval = -ENODEV; ++ goto hid_parse_fail; ++ } ++ + /* Starts the usb device and connects to upper interfaces hiddev and + * hidraw */ + retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); +diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c +index f6ba81d..f348f7f 100644 +--- a/drivers/hid/hid-zpff.c ++++ b/drivers/hid/hid-zpff.c +@@ -70,21 +70,13 @@ static int zpff_init(struct hid_device *hid) + struct hid_report *report; + struct hid_input *hidinput = list_entry(hid->inputs.next, + struct hid_input, list); +- struct list_head *report_list = +- &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct input_dev *dev = hidinput->input; +- int error; ++ int i, error; + +- if (list_empty(report_list)) { +- hid_err(hid, "no output report found\n"); +- return -ENODEV; +- } +- +- report = list_entry(report_list->next, struct hid_report, list); +- +- if (report->maxfield < 4) { +- hid_err(hid, "not enough fields in report\n"); +- return -ENODEV; ++ for (i = 0; i < 4; i++) { ++ report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, i, 1); ++ if (!report) ++ return -ENODEV; + } + + zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL); +diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c +index 7b3c068..62311ad 100644 +--- a/drivers/net/ethernet/sfc/rx.c ++++ b/drivers/net/ethernet/sfc/rx.c +@@ -311,8 +311,9 @@ static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue, + + index = rx_queue->added_count & rx_queue->ptr_mask; + new_buf = efx_rx_buffer(rx_queue, index); +- new_buf->dma_addr = rx_buf->dma_addr ^ (PAGE_SIZE >> 1); + new_buf->u.page = rx_buf->u.page; ++ new_buf->page_offset = rx_buf->page_offset ^ (PAGE_SIZE >> 1); ++ new_buf->dma_addr = state->dma_addr + new_buf->page_offset; + new_buf->len = rx_buf->len; + new_buf->flags = EFX_RX_BUF_PAGE; + ++rx_queue->added_count; +diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c +index 425e201..1db819b 100644 +--- a/drivers/net/usb/cdc_ether.c ++++ b/drivers/net/usb/cdc_ether.c +@@ -618,6 +618,11 @@ static const struct usb_device_id products [] = { + .bInterfaceProtocol = USB_CDC_PROTO_NONE, + .driver_info = (unsigned long)&wwan_info, + }, { ++ /* Telit modules */ ++ USB_VENDOR_AND_INTERFACE_INFO(0x1bc7, USB_CLASS_COMM, ++ USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), ++ .driver_info = (kernel_ulong_t) &wwan_info, ++}, { + USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, + USB_CDC_PROTO_NONE), + .driver_info = (unsigned long) &cdc_info, +diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c +index 72cb121..8ff177d 100644 +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c +@@ -2161,6 +2161,13 @@ static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev) + int i; + + /* ++ * First check if temperature compensation is supported. ++ */ ++ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); ++ if (!rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_TX_ALC)) ++ return 0; ++ ++ /* + * Read TSSI boundaries for temperature compensation from + * the EEPROM. + * +diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c +index a506360..0c2f912 100644 +--- a/fs/notify/fanotify/fanotify.c ++++ b/fs/notify/fanotify/fanotify.c +@@ -18,6 +18,12 @@ static bool should_merge(struct fsnotify_event *old, struct fsnotify_event *new) + old->tgid == new->tgid) { + switch (old->data_type) { + case (FSNOTIFY_EVENT_PATH): ++#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS ++ /* dont merge two permission events */ ++ if ((old->mask & FAN_ALL_PERM_EVENTS) && ++ (new->mask & FAN_ALL_PERM_EVENTS)) ++ return false; ++#endif + if ((old->path.mnt == new->path.mnt) && + (old->path.dentry == new->path.dentry)) + return true; +diff --git a/include/linux/hid.h b/include/linux/hid.h +index 8c933a8..3572ecd 100644 +--- a/include/linux/hid.h ++++ b/include/linux/hid.h +@@ -737,6 +737,10 @@ void hid_output_report(struct hid_report *report, __u8 *data); + struct hid_device *hid_allocate_device(void); + struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id); + int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); ++struct hid_report *hid_validate_values(struct hid_device *hid, ++ unsigned int type, unsigned int id, ++ unsigned int field_index, ++ unsigned int report_counts); + int hid_check_keys_pressed(struct hid_device *hid); + int hid_connect(struct hid_device *hid, unsigned int connect_mask); + void hid_disconnect(struct hid_device *hid); +diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h +index 89fb74e..e45ffad 100644 +--- a/include/linux/perf_event.h ++++ b/include/linux/perf_event.h +@@ -1063,7 +1063,7 @@ struct perf_cpu_context { + int exclusive; + struct list_head rotation_list; + int jiffies_interval; +- struct pmu *active_pmu; ++ struct pmu *unique_pmu; + struct perf_cgroup *cgrp; + }; + +diff --git a/kernel/cgroup.c b/kernel/cgroup.c +index 4eb1ed3..519c252 100644 +--- a/kernel/cgroup.c ++++ b/kernel/cgroup.c +@@ -3476,6 +3476,7 @@ static int cgroup_write_event_control(struct cgroup *cgrp, struct cftype *cft, + const char *buffer) + { + struct cgroup_event *event = NULL; ++ struct cgroup *cgrp_cfile; + unsigned int efd, cfd; + struct file *efile = NULL; + struct file *cfile = NULL; +@@ -3531,6 +3532,16 @@ static int cgroup_write_event_control(struct cgroup *cgrp, struct cftype *cft, + goto fail; + } + ++ /* ++ * The file to be monitored must be in the same cgroup as ++ * cgroup.event_control is. ++ */ ++ cgrp_cfile = __d_cgrp(cfile->f_dentry->d_parent); ++ if (cgrp_cfile != cgrp) { ++ ret = -EINVAL; ++ goto fail; ++ } ++ + if (!event->cft->register_event || !event->cft->unregister_event) { + ret = -EINVAL; + goto fail; +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 8e810ba..8e82398 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -368,6 +368,8 @@ void perf_cgroup_switch(struct task_struct *task, int mode) + + list_for_each_entry_rcu(pmu, &pmus, entry) { + cpuctx = this_cpu_ptr(pmu->pmu_cpu_context); ++ if (cpuctx->unique_pmu != pmu) ++ continue; /* ensure we process each cpuctx once */ + + /* + * perf_cgroup_events says at least one +@@ -391,9 +393,10 @@ void perf_cgroup_switch(struct task_struct *task, int mode) + + if (mode & PERF_CGROUP_SWIN) { + WARN_ON_ONCE(cpuctx->cgrp); +- /* set cgrp before ctxsw in to +- * allow event_filter_match() to not +- * have to pass task around ++ /* ++ * set cgrp before ctxsw in to allow ++ * event_filter_match() to not have to pass ++ * task around + */ + cpuctx->cgrp = perf_cgroup_from_task(task); + cpu_ctx_sched_in(cpuctx, EVENT_ALL, task); +@@ -4332,7 +4335,7 @@ static void perf_event_task_event(struct perf_task_event *task_event) + rcu_read_lock(); + list_for_each_entry_rcu(pmu, &pmus, entry) { + cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); +- if (cpuctx->active_pmu != pmu) ++ if (cpuctx->unique_pmu != pmu) + goto next; + perf_event_task_ctx(&cpuctx->ctx, task_event); + +@@ -4478,7 +4481,7 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event) + rcu_read_lock(); + list_for_each_entry_rcu(pmu, &pmus, entry) { + cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); +- if (cpuctx->active_pmu != pmu) ++ if (cpuctx->unique_pmu != pmu) + goto next; + perf_event_comm_ctx(&cpuctx->ctx, comm_event); + +@@ -4674,7 +4677,7 @@ got_name: + rcu_read_lock(); + list_for_each_entry_rcu(pmu, &pmus, entry) { + cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); +- if (cpuctx->active_pmu != pmu) ++ if (cpuctx->unique_pmu != pmu) + goto next; + perf_event_mmap_ctx(&cpuctx->ctx, mmap_event, + vma->vm_flags & VM_EXEC); +@@ -5750,8 +5753,8 @@ static void update_pmu_context(struct pmu *pmu, struct pmu *old_pmu) + + cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu); + +- if (cpuctx->active_pmu == old_pmu) +- cpuctx->active_pmu = pmu; ++ if (cpuctx->unique_pmu == old_pmu) ++ cpuctx->unique_pmu = pmu; + } + } + +@@ -5886,7 +5889,7 @@ skip_type: + cpuctx->ctx.pmu = pmu; + cpuctx->jiffies_interval = 1; + INIT_LIST_HEAD(&cpuctx->rotation_list); +- cpuctx->active_pmu = pmu; ++ cpuctx->unique_pmu = pmu; + } + + got_cpu_context: +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index da4512f..33c8b60 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -5190,11 +5190,15 @@ static void task_fork_fair(struct task_struct *p) + cfs_rq = task_cfs_rq(current); + curr = cfs_rq->curr; + +- if (unlikely(task_cpu(p) != this_cpu)) { +- rcu_read_lock(); +- __set_task_cpu(p, this_cpu); +- rcu_read_unlock(); +- } ++ /* ++ * Not only the cpu but also the task_group of the parent might have ++ * been changed after parent->se.parent,cfs_rq were copied to ++ * child->se.parent,cfs_rq. So call __set_task_cpu() to make those ++ * of child point to valid ones. ++ */ ++ rcu_read_lock(); ++ __set_task_cpu(p, this_cpu); ++ rcu_read_unlock(); + + update_curr(cfs_rq); + +diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c +index 2fdb05d..1ff51c9 100644 +--- a/net/sctp/sm_sideeffect.c ++++ b/net/sctp/sm_sideeffect.c +@@ -1610,9 +1610,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, + asoc->outqueue.outstanding_bytes; + sackh.num_gap_ack_blocks = 0; + sackh.num_dup_tsns = 0; +- chunk->subh.sack_hdr = &sackh; + sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK, +- SCTP_CHUNK(chunk)); ++ SCTP_SACKH(&sackh)); + break; + + case SCTP_CMD_DISCARD_PACKET: +diff --git a/scripts/kernel-doc b/scripts/kernel-doc +index 9b0c0b8..55ab5e4 100755 +--- a/scripts/kernel-doc ++++ b/scripts/kernel-doc +@@ -2045,6 +2045,9 @@ sub process_file($) { + + $section_counter = 0; + while () { ++ while (s/\\\s*$//) { ++ $_ .= ; ++ } + if ($state == 0) { + if (/$doc_start/o) { + $state = 1; # next line is always the function name +diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c +index 9593f27..5f5080f 100644 +--- a/tools/perf/util/map.c ++++ b/tools/perf/util/map.c +@@ -16,6 +16,7 @@ const char *map_type__name[MAP__NR_TYPES] = { + static inline int is_anon_memory(const char *filename) + { + return !strcmp(filename, "//anon") || ++ !strcmp(filename, "/dev/zero (deleted)") || + !strcmp(filename, "/anon_hugepage (deleted)"); + } + diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.64-65.patch b/patch/kernel/sun8i-default/0001-patch-3.4.64-65.patch new file mode 100644 index 000000000..e90426659 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.64-65.patch @@ -0,0 +1,544 @@ +diff --git a/Makefile b/Makefile +index 580b364..3a8897f 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 64 ++SUBLEVEL = 65 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c +index df1b604..bd70df6 100644 +--- a/arch/x86/kernel/reboot.c ++++ b/arch/x86/kernel/reboot.c +@@ -479,6 +479,22 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "Precision M6600"), + }, + }, ++ { /* Handle problems with rebooting on the Dell PowerEdge C6100. */ ++ .callback = set_pci_reboot, ++ .ident = "Dell PowerEdge C6100", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "C6100"), ++ }, ++ }, ++ { /* Some C6100 machines were shipped with vendor being 'Dell'. */ ++ .callback = set_pci_reboot, ++ .ident = "Dell PowerEdge C6100", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "C6100"), ++ }, ++ }, + { } + }; + +diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c +index 1e40637..454548c 100644 +--- a/arch/x86/platform/efi/efi.c ++++ b/arch/x86/platform/efi/efi.c +@@ -845,10 +845,13 @@ void __init efi_enter_virtual_mode(void) + + for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { + md = p; +- if (!(md->attribute & EFI_MEMORY_RUNTIME) && +- md->type != EFI_BOOT_SERVICES_CODE && +- md->type != EFI_BOOT_SERVICES_DATA) +- continue; ++ if (!(md->attribute & EFI_MEMORY_RUNTIME)) { ++#ifdef CONFIG_X86_64 ++ if (md->type != EFI_BOOT_SERVICES_CODE && ++ md->type != EFI_BOOT_SERVICES_DATA) ++#endif ++ continue; ++ } + + size = md->num_pages << EFI_PAGE_SHIFT; + end = md->phys_addr + size; +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 069725c..eee6cd3 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -625,7 +625,18 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, + DRM_DEBUG_KMS("aux_ch native nack\n"); + return -EREMOTEIO; + case AUX_NATIVE_REPLY_DEFER: +- udelay(100); ++ /* ++ * For now, just give more slack to branch devices. We ++ * could check the DPCD for I2C bit rate capabilities, ++ * and if available, adjust the interval. We could also ++ * be more careful with DP-to-Legacy adapters where a ++ * long legacy cable may force very low I2C bit rates. ++ */ ++ if (intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] & ++ DP_DWN_STRM_PORT_PRESENT) ++ usleep_range(500, 600); ++ else ++ usleep_range(300, 400); + continue; + default: + DRM_ERROR("aux_ch invalid native reply 0x%02x\n", +diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c +index 1209f15..2f555d7 100644 +--- a/drivers/gpu/drm/radeon/radeon_device.c ++++ b/drivers/gpu/drm/radeon/radeon_device.c +@@ -835,13 +835,22 @@ int radeon_device_init(struct radeon_device *rdev, + return r; + } + if ((radeon_testing & 1)) { +- radeon_test_moves(rdev); ++ if (rdev->accel_working) ++ radeon_test_moves(rdev); ++ else ++ DRM_INFO("radeon: acceleration disabled, skipping move tests\n"); + } + if ((radeon_testing & 2)) { +- radeon_test_syncing(rdev); ++ if (rdev->accel_working) ++ radeon_test_syncing(rdev); ++ else ++ DRM_INFO("radeon: acceleration disabled, skipping sync tests\n"); + } + if (radeon_benchmarking) { +- radeon_benchmark(rdev, radeon_benchmarking); ++ if (rdev->accel_working) ++ radeon_benchmark(rdev, radeon_benchmarking); ++ else ++ DRM_INFO("radeon: acceleration disabled, skipping benchmarks\n"); + } + return 0; + } +diff --git a/drivers/hid/hid-lg2ff.c b/drivers/hid/hid-lg2ff.c +index 3c31bc6..128f011 100644 +--- a/drivers/hid/hid-lg2ff.c ++++ b/drivers/hid/hid-lg2ff.c +@@ -66,26 +66,13 @@ int lg2ff_init(struct hid_device *hid) + struct hid_report *report; + struct hid_input *hidinput = list_entry(hid->inputs.next, + struct hid_input, list); +- struct list_head *report_list = +- &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct input_dev *dev = hidinput->input; + int error; + +- if (list_empty(report_list)) { +- hid_err(hid, "no output report found\n"); ++ /* Check that the report looks ok */ ++ report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7); ++ if (!report) + return -ENODEV; +- } +- +- report = list_entry(report_list->next, struct hid_report, list); +- +- if (report->maxfield < 1) { +- hid_err(hid, "output report is empty\n"); +- return -ENODEV; +- } +- if (report->field[0]->report_count < 7) { +- hid_err(hid, "not enough values in the field\n"); +- return -ENODEV; +- } + + lg2ff = kmalloc(sizeof(struct lg2ff_device), GFP_KERNEL); + if (!lg2ff) +diff --git a/drivers/hid/hid-lg3ff.c b/drivers/hid/hid-lg3ff.c +index f98644c..91f981f 100644 +--- a/drivers/hid/hid-lg3ff.c ++++ b/drivers/hid/hid-lg3ff.c +@@ -68,10 +68,11 @@ static int hid_lg3ff_play(struct input_dev *dev, void *data, + int x, y; + + /* +- * Maxusage should always be 63 (maximum fields) +- * likely a better way to ensure this data is clean ++ * Available values in the field should always be 63, but we only use up to ++ * 35. Instead, clear the entire area, however big it is. + */ +- memset(report->field[0]->value, 0, sizeof(__s32)*report->field[0]->maxusage); ++ memset(report->field[0]->value, 0, ++ sizeof(__s32) * report->field[0]->report_count); + + switch (effect->type) { + case FF_CONSTANT: +@@ -131,32 +132,14 @@ static const signed short ff3_joystick_ac[] = { + int lg3ff_init(struct hid_device *hid) + { + struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); +- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct input_dev *dev = hidinput->input; +- struct hid_report *report; +- struct hid_field *field; + const signed short *ff_bits = ff3_joystick_ac; + int error; + int i; + +- /* Find the report to use */ +- if (list_empty(report_list)) { +- hid_err(hid, "No output report found\n"); +- return -1; +- } +- + /* Check that the report looks ok */ +- report = list_entry(report_list->next, struct hid_report, list); +- if (!report) { +- hid_err(hid, "NULL output report\n"); +- return -1; +- } +- +- field = report->field[0]; +- if (!field) { +- hid_err(hid, "NULL field\n"); +- return -1; +- } ++ if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 35)) ++ return -ENODEV; + + /* Assume single fixed device G940 */ + for (i = 0; ff_bits[i] >= 0; i++) +diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c +index 6ecc9e2..44bb0a5 100644 +--- a/drivers/hid/hid-lg4ff.c ++++ b/drivers/hid/hid-lg4ff.c +@@ -339,33 +339,15 @@ static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *at + int lg4ff_init(struct hid_device *hid) + { + struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); +- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct input_dev *dev = hidinput->input; +- struct hid_report *report; +- struct hid_field *field; + struct lg4ff_device_entry *entry; + struct usb_device_descriptor *udesc; + int error, i, j; + __u16 bcdDevice, rev_maj, rev_min; + +- /* Find the report to use */ +- if (list_empty(report_list)) { +- hid_err(hid, "No output report found\n"); +- return -1; +- } +- + /* Check that the report looks ok */ +- report = list_entry(report_list->next, struct hid_report, list); +- if (!report) { +- hid_err(hid, "NULL output report\n"); ++ if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7)) + return -1; +- } +- +- field = report->field[0]; +- if (!field) { +- hid_err(hid, "NULL field\n"); +- return -1; +- } + + /* Check what wheel has been connected */ + for (i = 0; i < ARRAY_SIZE(lg4ff_devices); i++) { +diff --git a/drivers/hid/hid-lgff.c b/drivers/hid/hid-lgff.c +index 27bc54f..1d978daa 100644 +--- a/drivers/hid/hid-lgff.c ++++ b/drivers/hid/hid-lgff.c +@@ -130,27 +130,14 @@ static void hid_lgff_set_autocenter(struct input_dev *dev, u16 magnitude) + int lgff_init(struct hid_device* hid) + { + struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); +- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct input_dev *dev = hidinput->input; +- struct hid_report *report; +- struct hid_field *field; + const signed short *ff_bits = ff_joystick; + int error; + int i; + +- /* Find the report to use */ +- if (list_empty(report_list)) { +- hid_err(hid, "No output report found\n"); +- return -1; +- } +- + /* Check that the report looks ok */ +- report = list_entry(report_list->next, struct hid_report, list); +- field = report->field[0]; +- if (!field) { +- hid_err(hid, "NULL field\n"); +- return -1; +- } ++ if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7)) ++ return -ENODEV; + + for (i = 0; i < ARRAY_SIZE(devices); i++) { + if (dev->id.vendor == devices[i].idVendor && +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 70d62f5..73bea49 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -489,16 +489,25 @@ static int applesmc_init_smcreg_try(void) + { + struct applesmc_registers *s = &smcreg; + bool left_light_sensor, right_light_sensor; ++ unsigned int count; + u8 tmp[1]; + int ret; + + if (s->init_complete) + return 0; + +- ret = read_register_count(&s->key_count); ++ ret = read_register_count(&count); + if (ret) + return ret; + ++ if (s->cache && s->key_count != count) { ++ pr_warn("key count changed from %d to %d\n", ++ s->key_count, count); ++ kfree(s->cache); ++ s->cache = NULL; ++ } ++ s->key_count = count; ++ + if (!s->cache) + s->cache = kcalloc(s->key_count, sizeof(*s->cache), GFP_KERNEL); + if (!s->cache) +diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c +index 3ac4156..4caa8e6 100644 +--- a/drivers/md/dm-snap-persistent.c ++++ b/drivers/md/dm-snap-persistent.c +@@ -256,7 +256,7 @@ static int chunk_io(struct pstore *ps, void *area, chunk_t chunk, int rw, + */ + INIT_WORK_ONSTACK(&req.work, do_metadata); + queue_work(ps->metadata_wq, &req.work); +- flush_work(&req.work); ++ flush_workqueue(ps->metadata_wq); + + return req.result; + } +diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c +index ff62ddc..448050c 100644 +--- a/drivers/md/dm-snap.c ++++ b/drivers/md/dm-snap.c +@@ -721,17 +721,16 @@ static int calc_max_buckets(void) + */ + static int init_hash_tables(struct dm_snapshot *s) + { +- sector_t hash_size, cow_dev_size, origin_dev_size, max_buckets; ++ sector_t hash_size, cow_dev_size, max_buckets; + + /* + * Calculate based on the size of the original volume or + * the COW volume... + */ + cow_dev_size = get_dev_size(s->cow->bdev); +- origin_dev_size = get_dev_size(s->origin->bdev); + max_buckets = calc_max_buckets(); + +- hash_size = min(origin_dev_size, cow_dev_size) >> s->store->chunk_shift; ++ hash_size = cow_dev_size >> s->store->chunk_shift; + hash_size = min(hash_size, max_buckets); + + if (hash_size < 64) +diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c +index 628545d..1f34a34 100644 +--- a/drivers/staging/vt6656/main_usb.c ++++ b/drivers/staging/vt6656/main_usb.c +@@ -1220,6 +1220,8 @@ device_release_WPADEV(pDevice); + memset(pMgmt->abyCurrBSSID, 0, 6); + pMgmt->eCurrState = WMAC_STATE_IDLE; + ++ pDevice->flags &= ~DEVICE_FLAGS_OPENED; ++ + device_free_tx_bufs(pDevice); + device_free_rx_bufs(pDevice); + device_free_int_bufs(pDevice); +@@ -1231,7 +1233,6 @@ device_release_WPADEV(pDevice); + usb_free_urb(pDevice->pInterruptURB); + + BSSvClearNodeDBTable(pDevice, 0); +- pDevice->flags &=(~DEVICE_FLAGS_OPENED); + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close2 \n"); + +diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c +index 336b82d..371fe69 100644 +--- a/drivers/usb/core/devio.c ++++ b/drivers/usb/core/devio.c +@@ -684,6 +684,22 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, + if ((index & ~USB_DIR_IN) == 0) + return 0; + ret = findintfep(ps->dev, index); ++ if (ret < 0) { ++ /* ++ * Some not fully compliant Win apps seem to get ++ * index wrong and have the endpoint number here ++ * rather than the endpoint address (with the ++ * correct direction). Win does let this through, ++ * so we'll not reject it here but leave it to ++ * the device to not break KVM. But we warn. ++ */ ++ ret = findintfep(ps->dev, index ^ 0x80); ++ if (ret >= 0) ++ dev_info(&ps->dev->dev, ++ "%s: process %i (%s) requesting ep %02x but needs %02x\n", ++ __func__, task_pid_nr(current), ++ current->comm, index, index ^ 0x80); ++ } + if (ret >= 0) + ret = checkintf(ps, ret); + break; +diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c +index 8331893..e0478b7 100644 +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -287,7 +287,7 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend) + if (virt_dev->eps[i].ring && virt_dev->eps[i].ring->dequeue) + xhci_queue_stop_endpoint(xhci, slot_id, i, suspend); + } +- cmd->command_trb = xhci->cmd_ring->enqueue; ++ cmd->command_trb = xhci_find_next_enqueue(xhci->cmd_ring); + list_add_tail(&cmd->cmd_list, &virt_dev->cmd_list); + xhci_queue_stop_endpoint(xhci, slot_id, 0, suspend); + xhci_ring_cmd_db(xhci); +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index 1770ed5..87ee28e 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -122,6 +122,16 @@ static int enqueue_is_link_trb(struct xhci_ring *ring) + return TRB_TYPE_LINK_LE32(link->control); + } + ++union xhci_trb *xhci_find_next_enqueue(struct xhci_ring *ring) ++{ ++ /* Enqueue pointer can be left pointing to the link TRB, ++ * we must handle that ++ */ ++ if (TRB_TYPE_LINK_LE32(ring->enqueue->link.control)) ++ return ring->enq_seg->next->trbs; ++ return ring->enqueue; ++} ++ + /* Updates trb to point to the next TRB in the ring, and updates seg if the next + * TRB is in a new segment. This does not skip over link TRBs, and it does not + * effect the ring dequeue or enqueue pointers. +@@ -847,8 +857,12 @@ remove_finished_td: + /* Otherwise ring the doorbell(s) to restart queued transfers */ + ring_doorbell_for_active_rings(xhci, slot_id, ep_index); + } +- ep->stopped_td = NULL; +- ep->stopped_trb = NULL; ++ ++ /* Clear stopped_td and stopped_trb if endpoint is not halted */ ++ if (!(ep->ep_state & EP_HALTED)) { ++ ep->stopped_td = NULL; ++ ep->stopped_trb = NULL; ++ } + + /* + * Drop the lock and complete the URBs in the cancelled TD list. +@@ -1390,6 +1404,12 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, + inc_deq(xhci, xhci->cmd_ring); + return; + } ++ /* There is no command to handle if we get a stop event when the ++ * command ring is empty, event->cmd_trb points to the next ++ * unset command ++ */ ++ if (xhci->cmd_ring->dequeue == xhci->cmd_ring->enqueue) ++ return; + } + + switch (le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3]) +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 1504946..c8ea954 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -2582,15 +2582,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, + if (command) { + cmd_completion = command->completion; + cmd_status = &command->status; +- command->command_trb = xhci->cmd_ring->enqueue; +- +- /* Enqueue pointer can be left pointing to the link TRB, +- * we must handle that +- */ +- if (TRB_TYPE_LINK_LE32(command->command_trb->link.control)) +- command->command_trb = +- xhci->cmd_ring->enq_seg->next->trbs; +- ++ command->command_trb = xhci_find_next_enqueue(xhci->cmd_ring); + list_add_tail(&command->cmd_list, &virt_dev->cmd_list); + } else { + cmd_completion = &virt_dev->cmd_completion; +@@ -2598,7 +2590,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, + } + init_completion(cmd_completion); + +- cmd_trb = xhci->cmd_ring->dequeue; ++ cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring); + if (!ctx_change) + ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, + udev->slot_id, must_succeed); +@@ -3383,14 +3375,7 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) + + /* Attempt to submit the Reset Device command to the command ring */ + spin_lock_irqsave(&xhci->lock, flags); +- reset_device_cmd->command_trb = xhci->cmd_ring->enqueue; +- +- /* Enqueue pointer can be left pointing to the link TRB, +- * we must handle that +- */ +- if (TRB_TYPE_LINK_LE32(reset_device_cmd->command_trb->link.control)) +- reset_device_cmd->command_trb = +- xhci->cmd_ring->enq_seg->next->trbs; ++ reset_device_cmd->command_trb = xhci_find_next_enqueue(xhci->cmd_ring); + + list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list); + ret = xhci_queue_reset_device(xhci, slot_id); +@@ -3594,7 +3579,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) + union xhci_trb *cmd_trb; + + spin_lock_irqsave(&xhci->lock, flags); +- cmd_trb = xhci->cmd_ring->dequeue; ++ cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring); + ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0); + if (ret) { + spin_unlock_irqrestore(&xhci->lock, flags); +@@ -3721,7 +3706,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) + xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); + + spin_lock_irqsave(&xhci->lock, flags); +- cmd_trb = xhci->cmd_ring->dequeue; ++ cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring); + ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma, + udev->slot_id); + if (ret) { +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index a54a408..71dd138 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1811,6 +1811,7 @@ int xhci_cancel_cmd(struct xhci_hcd *xhci, struct xhci_command *command, + union xhci_trb *cmd_trb); + void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id, + unsigned int ep_index, unsigned int stream_id); ++union xhci_trb *xhci_find_next_enqueue(struct xhci_ring *ring); + + /* xHCI roothub code */ + void xhci_set_link_state(struct xhci_hcd *xhci, __le32 __iomem **port_array, +diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c +index 84717ce..7895983 100644 +--- a/sound/core/compress_offload.c ++++ b/sound/core/compress_offload.c +@@ -663,7 +663,8 @@ static int snd_compress_dev_disconnect(struct snd_device *device) + struct snd_compr *compr; + + compr = device->device_data; +- snd_unregister_device(compr->direction, compr->card, compr->device); ++ snd_unregister_device(SNDRV_DEVICE_TYPE_COMPRESS, compr->card, ++ compr->device); + return 0; + } + diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.65-66.patch b/patch/kernel/sun8i-default/0001-patch-3.4.65-66.patch new file mode 100644 index 000000000..7775eae0f --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.65-66.patch @@ -0,0 +1,1583 @@ +diff --git a/Makefile b/Makefile +index 3a8897f..e9587ab 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 65 ++SUBLEVEL = 66 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c +index 8f5813b..056cfbe 100644 +--- a/arch/arm/mm/init.c ++++ b/arch/arm/mm/init.c +@@ -98,6 +98,9 @@ void show_mem(unsigned int filter) + printk("Mem-info:\n"); + show_free_areas(filter); + ++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT) ++ return; ++ + for_each_bank (i, mi) { + struct membank *bank = &mi->bank[i]; + unsigned int pfn1, pfn2; +diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c +index 1516d1d..f2652fc 100644 +--- a/arch/ia64/mm/contig.c ++++ b/arch/ia64/mm/contig.c +@@ -47,6 +47,8 @@ void show_mem(unsigned int filter) + printk(KERN_INFO "Mem-info:\n"); + show_free_areas(filter); + printk(KERN_INFO "Node memory in pages:\n"); ++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT) ++ return; + for_each_online_pgdat(pgdat) { + unsigned long present; + unsigned long flags; +diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c +index c641333..2230817 100644 +--- a/arch/ia64/mm/discontig.c ++++ b/arch/ia64/mm/discontig.c +@@ -623,6 +623,8 @@ void show_mem(unsigned int filter) + + printk(KERN_INFO "Mem-info:\n"); + show_free_areas(filter); ++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT) ++ return; + printk(KERN_INFO "Node memory in pages:\n"); + for_each_online_pgdat(pgdat) { + unsigned long present; +diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c +index 82f364e..0b62162 100644 +--- a/arch/parisc/mm/init.c ++++ b/arch/parisc/mm/init.c +@@ -685,6 +685,8 @@ void show_mem(unsigned int filter) + + printk(KERN_INFO "Mem-info:\n"); + show_free_areas(filter); ++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT) ++ return; + #ifndef CONFIG_DISCONTIGMEM + i = max_mapnr; + while (i-- > 0) { +diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c +index 359f078..b2f4a8ed 100644 +--- a/arch/powerpc/kernel/iommu.c ++++ b/arch/powerpc/kernel/iommu.c +@@ -501,7 +501,7 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid) + /* number of bytes needed for the bitmap */ + sz = (tbl->it_size + 7) >> 3; + +- page = alloc_pages_node(nid, GFP_ATOMIC, get_order(sz)); ++ page = alloc_pages_node(nid, GFP_KERNEL, get_order(sz)); + if (!page) + panic("iommu_init_table: Can't allocate %ld bytes\n", sz); + tbl->it_map = page_address(page); +diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c +index a3a9990..cfe0069 100644 +--- a/arch/powerpc/kernel/vio.c ++++ b/arch/powerpc/kernel/vio.c +@@ -1341,11 +1341,15 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, + const char *cp; + + dn = dev->of_node; +- if (!dn) +- return -ENODEV; ++ if (!dn) { ++ strcat(buf, "\n"); ++ return strlen(buf); ++ } + cp = of_get_property(dn, "compatible", NULL); +- if (!cp) +- return -ENODEV; ++ if (!cp) { ++ strcat(buf, "\n"); ++ return strlen(buf); ++ } + + return sprintf(buf, "vio:T%sS%s\n", vio_dev->type, cp); + } +diff --git a/arch/powerpc/lib/checksum_64.S b/arch/powerpc/lib/checksum_64.S +index 18245af..afa2eba 100644 +--- a/arch/powerpc/lib/checksum_64.S ++++ b/arch/powerpc/lib/checksum_64.S +@@ -272,8 +272,8 @@ _GLOBAL(csum_partial_copy_generic) + rldicl. r6,r3,64-1,64-2 /* r6 = (r3 & 0x3) >> 1 */ + beq .Lcopy_aligned + +- li r7,4 +- sub r6,r7,r6 ++ li r9,4 ++ sub r6,r9,r6 + mtctr r6 + + 1: +diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S +index f445e98..cfabc3d 100644 +--- a/arch/sparc/kernel/entry.S ++++ b/arch/sparc/kernel/entry.S +@@ -1177,7 +1177,7 @@ sys_sigreturn: + nop + + call syscall_trace +- nop ++ mov 1, %o1 + + 1: + /* We don't want to muck with user registers like a +diff --git a/arch/sparc/kernel/ktlb.S b/arch/sparc/kernel/ktlb.S +index 79f3103..7c00735 100644 +--- a/arch/sparc/kernel/ktlb.S ++++ b/arch/sparc/kernel/ktlb.S +@@ -25,11 +25,10 @@ kvmap_itlb: + */ + kvmap_itlb_4v: + +-kvmap_itlb_nonlinear: + /* Catch kernel NULL pointer calls. */ + sethi %hi(PAGE_SIZE), %g5 + cmp %g4, %g5 +- bleu,pn %xcc, kvmap_dtlb_longpath ++ blu,pn %xcc, kvmap_itlb_longpath + nop + + KERN_TSB_LOOKUP_TL1(%g4, %g6, %g5, %g1, %g2, %g3, kvmap_itlb_load) +diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S +index 7f5f65d..817187d 100644 +--- a/arch/sparc/kernel/syscalls.S ++++ b/arch/sparc/kernel/syscalls.S +@@ -147,7 +147,7 @@ linux_syscall_trace32: + srl %i4, 0, %o4 + srl %i1, 0, %o1 + srl %i2, 0, %o2 +- ba,pt %xcc, 2f ++ ba,pt %xcc, 5f + srl %i3, 0, %o3 + + linux_syscall_trace: +@@ -177,13 +177,13 @@ linux_sparc_syscall32: + srl %i1, 0, %o1 ! IEU0 Group + ldx [%g6 + TI_FLAGS], %l0 ! Load + +- srl %i5, 0, %o5 ! IEU1 ++ srl %i3, 0, %o3 ! IEU0 + srl %i2, 0, %o2 ! IEU0 Group + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 + bne,pn %icc, linux_syscall_trace32 ! CTI + mov %i0, %l5 ! IEU1 +- call %l7 ! CTI Group brk forced +- srl %i3, 0, %o3 ! IEU0 ++5: call %l7 ! CTI Group brk forced ++ srl %i5, 0, %o5 ! IEU1 + ba,a,pt %xcc, 3f + + /* Linux native system calls enter here... */ +diff --git a/arch/sparc/kernel/trampoline_64.S b/arch/sparc/kernel/trampoline_64.S +index da1b781..8fa84a3 100644 +--- a/arch/sparc/kernel/trampoline_64.S ++++ b/arch/sparc/kernel/trampoline_64.S +@@ -131,7 +131,6 @@ startup_continue: + clr %l5 + sethi %hi(num_kernel_image_mappings), %l6 + lduw [%l6 + %lo(num_kernel_image_mappings)], %l6 +- add %l6, 1, %l6 + + mov 15, %l7 + BRANCH_IF_ANY_CHEETAH(g1,g5,2f) +@@ -224,7 +223,6 @@ niagara_lock_tlb: + clr %l5 + sethi %hi(num_kernel_image_mappings), %l6 + lduw [%l6 + %lo(num_kernel_image_mappings)], %l6 +- add %l6, 1, %l6 + + 1: + mov HV_FAST_MMU_MAP_PERM_ADDR, %o5 +diff --git a/arch/sparc/lib/ksyms.c b/arch/sparc/lib/ksyms.c +index f73c224..0b59bd3 100644 +--- a/arch/sparc/lib/ksyms.c ++++ b/arch/sparc/lib/ksyms.c +@@ -125,15 +125,6 @@ EXPORT_SYMBOL(___copy_from_user); + EXPORT_SYMBOL(___copy_in_user); + EXPORT_SYMBOL(__clear_user); + +-/* RW semaphores */ +-EXPORT_SYMBOL(__down_read); +-EXPORT_SYMBOL(__down_read_trylock); +-EXPORT_SYMBOL(__down_write); +-EXPORT_SYMBOL(__down_write_trylock); +-EXPORT_SYMBOL(__up_read); +-EXPORT_SYMBOL(__up_write); +-EXPORT_SYMBOL(__downgrade_write); +- + /* Atomic counter implementation. */ + EXPORT_SYMBOL(atomic_add); + EXPORT_SYMBOL(atomic_add_ret); +diff --git a/arch/tile/include/asm/percpu.h b/arch/tile/include/asm/percpu.h +index 63294f5..4f7ae39 100644 +--- a/arch/tile/include/asm/percpu.h ++++ b/arch/tile/include/asm/percpu.h +@@ -15,9 +15,37 @@ + #ifndef _ASM_TILE_PERCPU_H + #define _ASM_TILE_PERCPU_H + +-register unsigned long __my_cpu_offset __asm__("tp"); +-#define __my_cpu_offset __my_cpu_offset +-#define set_my_cpu_offset(tp) (__my_cpu_offset = (tp)) ++register unsigned long my_cpu_offset_reg asm("tp"); ++ ++#ifdef CONFIG_PREEMPT ++/* ++ * For full preemption, we can't just use the register variable ++ * directly, since we need barrier() to hazard against it, causing the ++ * compiler to reload anything computed from a previous "tp" value. ++ * But we also don't want to use volatile asm, since we'd like the ++ * compiler to be able to cache the value across multiple percpu reads. ++ * So we use a fake stack read as a hazard against barrier(). ++ * The 'U' constraint is like 'm' but disallows postincrement. ++ */ ++static inline unsigned long __my_cpu_offset(void) ++{ ++ unsigned long tp; ++ register unsigned long *sp asm("sp"); ++ asm("move %0, tp" : "=r" (tp) : "U" (*sp)); ++ return tp; ++} ++#define __my_cpu_offset __my_cpu_offset() ++#else ++/* ++ * We don't need to hazard against barrier() since "tp" doesn't ever ++ * change with PREEMPT_NONE, and with PREEMPT_VOLUNTARY it only ++ * changes at function call points, at which we are already re-reading ++ * the value of "tp" due to "my_cpu_offset_reg" being a global variable. ++ */ ++#define __my_cpu_offset my_cpu_offset_reg ++#endif ++ ++#define set_my_cpu_offset(tp) (my_cpu_offset_reg = (tp)) + + #include + +diff --git a/arch/unicore32/mm/init.c b/arch/unicore32/mm/init.c +index de186bd..6444828 100644 +--- a/arch/unicore32/mm/init.c ++++ b/arch/unicore32/mm/init.c +@@ -66,6 +66,9 @@ void show_mem(unsigned int filter) + printk(KERN_DEFAULT "Mem-info:\n"); + show_free_areas(filter); + ++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT) ++ return; ++ + for_each_bank(i, mi) { + struct membank *bank = &mi->bank[i]; + unsigned int pfn1, pfn2; +diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c +index f40acef..a6977e1 100644 +--- a/drivers/acpi/acpi_ipmi.c ++++ b/drivers/acpi/acpi_ipmi.c +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + + MODULE_AUTHOR("Zhao Yakui"); + MODULE_DESCRIPTION("ACPI IPMI Opregion driver"); +@@ -57,7 +58,7 @@ struct acpi_ipmi_device { + struct list_head head; + /* the IPMI request message list */ + struct list_head tx_msg_list; +- struct mutex tx_msg_lock; ++ spinlock_t tx_msg_lock; + acpi_handle handle; + struct pnp_dev *pnp_dev; + ipmi_user_t user_interface; +@@ -147,6 +148,7 @@ static void acpi_format_ipmi_msg(struct acpi_ipmi_msg *tx_msg, + struct kernel_ipmi_msg *msg; + struct acpi_ipmi_buffer *buffer; + struct acpi_ipmi_device *device; ++ unsigned long flags; + + msg = &tx_msg->tx_message; + /* +@@ -177,10 +179,10 @@ static void acpi_format_ipmi_msg(struct acpi_ipmi_msg *tx_msg, + + /* Get the msgid */ + device = tx_msg->device; +- mutex_lock(&device->tx_msg_lock); ++ spin_lock_irqsave(&device->tx_msg_lock, flags); + device->curr_msgid++; + tx_msg->tx_msgid = device->curr_msgid; +- mutex_unlock(&device->tx_msg_lock); ++ spin_unlock_irqrestore(&device->tx_msg_lock, flags); + } + + static void acpi_format_ipmi_response(struct acpi_ipmi_msg *msg, +@@ -242,6 +244,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) + int msg_found = 0; + struct acpi_ipmi_msg *tx_msg; + struct pnp_dev *pnp_dev = ipmi_device->pnp_dev; ++ unsigned long flags; + + if (msg->user != ipmi_device->user_interface) { + dev_warn(&pnp_dev->dev, "Unexpected response is returned. " +@@ -250,7 +253,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) + ipmi_free_recv_msg(msg); + return; + } +- mutex_lock(&ipmi_device->tx_msg_lock); ++ spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); + list_for_each_entry(tx_msg, &ipmi_device->tx_msg_list, head) { + if (msg->msgid == tx_msg->tx_msgid) { + msg_found = 1; +@@ -258,7 +261,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) + } + } + +- mutex_unlock(&ipmi_device->tx_msg_lock); ++ spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); + if (!msg_found) { + dev_warn(&pnp_dev->dev, "Unexpected response (msg id %ld) is " + "returned.\n", msg->msgid); +@@ -378,6 +381,7 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address address, + struct acpi_ipmi_device *ipmi_device = handler_context; + int err, rem_time; + acpi_status status; ++ unsigned long flags; + /* + * IPMI opregion message. + * IPMI message is firstly written to the BMC and system software +@@ -395,9 +399,9 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address address, + return AE_NO_MEMORY; + + acpi_format_ipmi_msg(tx_msg, address, value); +- mutex_lock(&ipmi_device->tx_msg_lock); ++ spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); + list_add_tail(&tx_msg->head, &ipmi_device->tx_msg_list); +- mutex_unlock(&ipmi_device->tx_msg_lock); ++ spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); + err = ipmi_request_settime(ipmi_device->user_interface, + &tx_msg->addr, + tx_msg->tx_msgid, +@@ -413,9 +417,9 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address address, + status = AE_OK; + + end_label: +- mutex_lock(&ipmi_device->tx_msg_lock); ++ spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); + list_del(&tx_msg->head); +- mutex_unlock(&ipmi_device->tx_msg_lock); ++ spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); + kfree(tx_msg); + return status; + } +@@ -457,7 +461,7 @@ static void acpi_add_ipmi_device(struct acpi_ipmi_device *ipmi_device) + + INIT_LIST_HEAD(&ipmi_device->head); + +- mutex_init(&ipmi_device->tx_msg_lock); ++ spin_lock_init(&ipmi_device->tx_msg_lock); + INIT_LIST_HEAD(&ipmi_device->tx_msg_list); + ipmi_install_space_handler(ipmi_device); + +diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c +index d3446f6..d7ad865 100644 +--- a/drivers/block/cciss.c ++++ b/drivers/block/cciss.c +@@ -1186,6 +1186,7 @@ static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode, + int err; + u32 cp; + ++ memset(&arg64, 0, sizeof(arg64)); + err = 0; + err |= + copy_from_user(&arg64.LUN_info, &arg32->LUN_info, +diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c +index 9125bbe..504bc16 100644 +--- a/drivers/block/cpqarray.c ++++ b/drivers/block/cpqarray.c +@@ -1195,6 +1195,7 @@ out_passthru: + ida_pci_info_struct pciinfo; + + if (!arg) return -EINVAL; ++ memset(&pciinfo, 0, sizeof(pciinfo)); + pciinfo.bus = host->pci_dev->bus->number; + pciinfo.dev_fn = host->pci_dev->devfn; + pciinfo.board_id = host->board_id; +diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c +index 180f523..d5ce453 100644 +--- a/drivers/dma/imx-dma.c ++++ b/drivers/dma/imx-dma.c +@@ -373,17 +373,18 @@ static void dma_irq_handle_channel(struct imxdma_channel *imxdmac) + struct imxdma_engine *imxdma = imxdmac->imxdma; + int chno = imxdmac->channel; + struct imxdma_desc *desc; ++ unsigned long flags; + +- spin_lock(&imxdma->lock); ++ spin_lock_irqsave(&imxdma->lock, flags); + if (list_empty(&imxdmac->ld_active)) { +- spin_unlock(&imxdma->lock); ++ spin_unlock_irqrestore(&imxdma->lock, flags); + goto out; + } + + desc = list_first_entry(&imxdmac->ld_active, + struct imxdma_desc, + node); +- spin_unlock(&imxdma->lock); ++ spin_unlock_irqrestore(&imxdma->lock, flags); + + if (desc->sg) { + u32 tmp; +@@ -455,7 +456,6 @@ static int imxdma_xfer_desc(struct imxdma_desc *d) + { + struct imxdma_channel *imxdmac = to_imxdma_chan(d->desc.chan); + struct imxdma_engine *imxdma = imxdmac->imxdma; +- unsigned long flags; + int slot = -1; + int i; + +@@ -463,7 +463,6 @@ static int imxdma_xfer_desc(struct imxdma_desc *d) + switch (d->type) { + case IMXDMA_DESC_INTERLEAVED: + /* Try to get a free 2D slot */ +- spin_lock_irqsave(&imxdma->lock, flags); + for (i = 0; i < IMX_DMA_2D_SLOTS; i++) { + if ((imxdma->slots_2d[i].count > 0) && + ((imxdma->slots_2d[i].xsr != d->x) || +@@ -473,10 +472,8 @@ static int imxdma_xfer_desc(struct imxdma_desc *d) + slot = i; + break; + } +- if (slot < 0) { +- spin_unlock_irqrestore(&imxdma->lock, flags); ++ if (slot < 0) + return -EBUSY; +- } + + imxdma->slots_2d[slot].xsr = d->x; + imxdma->slots_2d[slot].ysr = d->y; +@@ -485,7 +482,6 @@ static int imxdma_xfer_desc(struct imxdma_desc *d) + + imxdmac->slot_2d = slot; + imxdmac->enabled_2d = true; +- spin_unlock_irqrestore(&imxdma->lock, flags); + + if (slot == IMX_DMA_2D_SLOT_A) { + d->config_mem &= ~CCR_MSEL_B; +@@ -561,18 +557,17 @@ static void imxdma_tasklet(unsigned long data) + struct imxdma_channel *imxdmac = (void *)data; + struct imxdma_engine *imxdma = imxdmac->imxdma; + struct imxdma_desc *desc; ++ unsigned long flags; + +- spin_lock(&imxdma->lock); ++ spin_lock_irqsave(&imxdma->lock, flags); + + if (list_empty(&imxdmac->ld_active)) { + /* Someone might have called terminate all */ +- goto out; ++ spin_unlock_irqrestore(&imxdma->lock, flags); ++ return; + } + desc = list_first_entry(&imxdmac->ld_active, struct imxdma_desc, node); + +- if (desc->desc.callback) +- desc->desc.callback(desc->desc.callback_param); +- + /* If we are dealing with a cyclic descriptor keep it on ld_active + * and dont mark the descripor as complete. + * Only in non-cyclic cases it would be marked as complete +@@ -599,7 +594,11 @@ static void imxdma_tasklet(unsigned long data) + __func__, imxdmac->channel); + } + out: +- spin_unlock(&imxdma->lock); ++ spin_unlock_irqrestore(&imxdma->lock, flags); ++ ++ if (desc->desc.callback) ++ desc->desc.callback(desc->desc.callback_param); ++ + } + + static int imxdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, +@@ -823,7 +822,7 @@ static struct dma_async_tx_descriptor *imxdma_prep_dma_cyclic( + kfree(imxdmac->sg_list); + + imxdmac->sg_list = kcalloc(periods + 1, +- sizeof(struct scatterlist), GFP_KERNEL); ++ sizeof(struct scatterlist), GFP_ATOMIC); + if (!imxdmac->sg_list) + return NULL; + +diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c +index daf21b8..2309f2e 100644 +--- a/drivers/infiniband/ulp/srpt/ib_srpt.c ++++ b/drivers/infiniband/ulp/srpt/ib_srpt.c +@@ -1610,7 +1610,7 @@ static int srpt_build_tskmgmt_rsp(struct srpt_rdma_ch *ch, + int resp_data_len; + int resp_len; + +- resp_data_len = (rsp_code == SRP_TSK_MGMT_SUCCESS) ? 0 : 4; ++ resp_data_len = 4; + resp_len = sizeof(*srp_rsp) + resp_data_len; + + srp_rsp = ioctx->ioctx.buf; +@@ -1622,11 +1622,9 @@ static int srpt_build_tskmgmt_rsp(struct srpt_rdma_ch *ch, + + atomic_xchg(&ch->req_lim_delta, 0)); + srp_rsp->tag = tag; + +- if (rsp_code != SRP_TSK_MGMT_SUCCESS) { +- srp_rsp->flags |= SRP_RSP_FLAG_RSPVALID; +- srp_rsp->resp_data_len = cpu_to_be32(resp_data_len); +- srp_rsp->data[3] = rsp_code; +- } ++ srp_rsp->flags |= SRP_RSP_FLAG_RSPVALID; ++ srp_rsp->resp_data_len = cpu_to_be32(resp_data_len); ++ srp_rsp->data[3] = rsp_code; + + return resp_len; + } +@@ -2373,6 +2371,8 @@ static void srpt_release_channel_work(struct work_struct *w) + transport_deregister_session(ch->sess); + ch->sess = NULL; + ++ ib_destroy_cm_id(ch->cm_id); ++ + srpt_destroy_ch_ib(ch); + + srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_ring, +@@ -2383,8 +2383,6 @@ static void srpt_release_channel_work(struct work_struct *w) + list_del(&ch->list); + spin_unlock_irq(&sdev->spinlock); + +- ib_destroy_cm_id(ch->cm_id); +- + if (ch->release_done) + complete(ch->release_done); + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 80103bb..098581a 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1933,6 +1933,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) + struct bonding *bond = netdev_priv(bond_dev); + struct slave *slave, *oldcurrent; + struct sockaddr addr; ++ int old_flags = bond_dev->flags; + netdev_features_t old_features = bond_dev->features; + + /* slave is not a slave or master is not master of this slave */ +@@ -2066,12 +2067,18 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) + * already taken care of above when we detached the slave + */ + if (!USES_PRIMARY(bond->params.mode)) { +- /* unset promiscuity level from slave */ +- if (bond_dev->flags & IFF_PROMISC) ++ /* unset promiscuity level from slave ++ * NOTE: The NETDEV_CHANGEADDR call above may change the value ++ * of the IFF_PROMISC flag in the bond_dev, but we need the ++ * value of that flag before that change, as that was the value ++ * when this slave was attached, so we cache at the start of the ++ * function and use it here. Same goes for ALLMULTI below ++ */ ++ if (old_flags & IFF_PROMISC) + dev_set_promiscuity(slave_dev, -1); + + /* unset allmulti level from slave */ +- if (bond_dev->flags & IFF_ALLMULTI) ++ if (old_flags & IFF_ALLMULTI) + dev_set_allmulti(slave_dev, -1); + + /* flush master's mc_list from slave */ +diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c +index 0819a74..d5de9a4 100644 +--- a/drivers/net/ethernet/freescale/gianfar.c ++++ b/drivers/net/ethernet/freescale/gianfar.c +@@ -394,7 +394,13 @@ static void gfar_init_mac(struct net_device *ndev) + if (ndev->features & NETIF_F_IP_CSUM) + tctrl |= TCTRL_INIT_CSUM; + +- tctrl |= TCTRL_TXSCHED_PRIO; ++ if (priv->prio_sched_en) ++ tctrl |= TCTRL_TXSCHED_PRIO; ++ else { ++ tctrl |= TCTRL_TXSCHED_WRRS; ++ gfar_write(®s->tr03wt, DEFAULT_WRRS_WEIGHT); ++ gfar_write(®s->tr47wt, DEFAULT_WRRS_WEIGHT); ++ } + + gfar_write(®s->tctrl, tctrl); + +@@ -1153,6 +1159,9 @@ static int gfar_probe(struct platform_device *ofdev) + priv->rx_filer_enable = 1; + /* Enable most messages by default */ + priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1; ++ /* use pritority h/w tx queue scheduling for single queue devices */ ++ if (priv->num_tx_queues == 1) ++ priv->prio_sched_en = 1; + + /* Carrier starts down, phylib will bring it up */ + netif_carrier_off(dev); +diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h +index 4c9f8d4..348b6dd 100644 +--- a/drivers/net/ethernet/freescale/gianfar.h ++++ b/drivers/net/ethernet/freescale/gianfar.h +@@ -301,8 +301,16 @@ extern const char gfar_driver_version[]; + #define TCTRL_TFCPAUSE 0x00000008 + #define TCTRL_TXSCHED_MASK 0x00000006 + #define TCTRL_TXSCHED_INIT 0x00000000 ++/* priority scheduling */ + #define TCTRL_TXSCHED_PRIO 0x00000002 ++/* weighted round-robin scheduling (WRRS) */ + #define TCTRL_TXSCHED_WRRS 0x00000004 ++/* default WRRS weight and policy setting, ++ * tailored to the tr03wt and tr47wt registers: ++ * equal weight for all Tx Qs, measured in 64byte units ++ */ ++#define DEFAULT_WRRS_WEIGHT 0x18181818 ++ + #define TCTRL_INIT_CSUM (TCTRL_TUCSEN | TCTRL_IPCSEN) + + #define IEVENT_INIT_CLEAR 0xffffffff +@@ -1098,7 +1106,8 @@ struct gfar_private { + extended_hash:1, + bd_stash_en:1, + rx_filer_enable:1, +- wol_en:1; /* Wake-on-LAN enabled */ ++ wol_en:1, /* Wake-on-LAN enabled */ ++ prio_sched_en:1; /* Enable priorty based Tx scheduling in Hw */ + unsigned short padding; + + /* PHY stuff */ +diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c +index 4c76db4..5fa0880 100644 +--- a/drivers/net/ethernet/via/via-rhine.c ++++ b/drivers/net/ethernet/via/via-rhine.c +@@ -32,7 +32,7 @@ + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + + #define DRV_NAME "via-rhine" +-#define DRV_VERSION "1.5.0" ++#define DRV_VERSION "1.5.1" + #define DRV_RELDATE "2010-10-09" + + #include +@@ -1684,7 +1684,12 @@ static netdev_tx_t rhine_start_tx(struct sk_buff *skb, + cpu_to_le32(TXDESC | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN)); + + if (unlikely(vlan_tx_tag_present(skb))) { +- rp->tx_ring[entry].tx_status = cpu_to_le32((vlan_tx_tag_get(skb)) << 16); ++ u16 vid_pcp = vlan_tx_tag_get(skb); ++ ++ /* drop CFI/DEI bit, register needs VID and PCP */ ++ vid_pcp = (vid_pcp & VLAN_VID_MASK) | ++ ((vid_pcp & VLAN_PRIO_MASK) >> 1); ++ rp->tx_ring[entry].tx_status = cpu_to_le32((vid_pcp) << 16); + /* request tagging */ + rp->tx_ring[entry].desc_length |= cpu_to_le32(0x020000); + } +diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c +index d21591a..5e5b791 100644 +--- a/drivers/net/ethernet/xilinx/ll_temac_main.c ++++ b/drivers/net/ethernet/xilinx/ll_temac_main.c +@@ -308,6 +308,12 @@ static int temac_dma_bd_init(struct net_device *ndev) + lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1))); + lp->dma_out(lp, TX_CURDESC_PTR, lp->tx_bd_p); + ++ /* Init descriptor indexes */ ++ lp->tx_bd_ci = 0; ++ lp->tx_bd_next = 0; ++ lp->tx_bd_tail = 0; ++ lp->rx_bd_ci = 0; ++ + return 0; + + out: +diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c +index f617566..8327cc5 100644 +--- a/drivers/net/ppp/pptp.c ++++ b/drivers/net/ppp/pptp.c +@@ -281,7 +281,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) + nf_reset(skb); + + skb->ip_summed = CHECKSUM_NONE; +- ip_select_ident(iph, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + ip_send_check(iph); + + ip_local_out(skb); +diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c +index b972263..905b16f 100644 +--- a/drivers/net/usb/dm9601.c ++++ b/drivers/net/usb/dm9601.c +@@ -384,7 +384,7 @@ static void dm9601_set_multicast(struct net_device *net) + rx_ctl |= 0x02; + } else if (net->flags & IFF_ALLMULTI || + netdev_mc_count(net) > DM_MAX_MCAST) { +- rx_ctl |= 0x04; ++ rx_ctl |= 0x08; + } else if (!netdev_mc_empty(net)) { + struct netdev_hw_addr *ha; + +diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c +index af30777..c31ac08 100644 +--- a/drivers/net/wireless/p54/p54usb.c ++++ b/drivers/net/wireless/p54/p54usb.c +@@ -83,6 +83,7 @@ static struct usb_device_id p54u_table[] = { + {USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */ + {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ + {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ ++ {USB_DEVICE(0x07aa, 0x0020)}, /* Corega WLUSB2GTST USB */ + {USB_DEVICE(0x0803, 0x4310)}, /* Zoom 4410a */ + {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ + {USB_DEVICE(0x083a, 0x4531)}, /* T-Com Sinus 154 data II */ +diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h +index 717d3ba..38c51ea 100644 +--- a/drivers/net/wireless/rtlwifi/wifi.h ++++ b/drivers/net/wireless/rtlwifi/wifi.h +@@ -1638,7 +1638,7 @@ struct rtl_priv { + that it points to the data allocated + beyond this structure like: + rtl_pci_priv or rtl_usb_priv */ +- u8 priv[0]; ++ u8 priv[0] __aligned(sizeof(void *)); + }; + + #define rtl_priv(hw) (((struct rtl_priv *)(hw)->priv)) +diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c +index 394ed9e..4aa30d8 100644 +--- a/drivers/scsi/esp_scsi.c ++++ b/drivers/scsi/esp_scsi.c +@@ -530,7 +530,7 @@ static int esp_need_to_nego_sync(struct esp_target_data *tp) + static int esp_alloc_lun_tag(struct esp_cmd_entry *ent, + struct esp_lun_data *lp) + { +- if (!ent->tag[0]) { ++ if (!ent->orig_tag[0]) { + /* Non-tagged, slot already taken? */ + if (lp->non_tagged_cmd) + return -EBUSY; +@@ -564,9 +564,9 @@ static int esp_alloc_lun_tag(struct esp_cmd_entry *ent, + return -EBUSY; + } + +- BUG_ON(lp->tagged_cmds[ent->tag[1]]); ++ BUG_ON(lp->tagged_cmds[ent->orig_tag[1]]); + +- lp->tagged_cmds[ent->tag[1]] = ent; ++ lp->tagged_cmds[ent->orig_tag[1]] = ent; + lp->num_tagged++; + + return 0; +@@ -575,9 +575,9 @@ static int esp_alloc_lun_tag(struct esp_cmd_entry *ent, + static void esp_free_lun_tag(struct esp_cmd_entry *ent, + struct esp_lun_data *lp) + { +- if (ent->tag[0]) { +- BUG_ON(lp->tagged_cmds[ent->tag[1]] != ent); +- lp->tagged_cmds[ent->tag[1]] = NULL; ++ if (ent->orig_tag[0]) { ++ BUG_ON(lp->tagged_cmds[ent->orig_tag[1]] != ent); ++ lp->tagged_cmds[ent->orig_tag[1]] = NULL; + lp->num_tagged--; + } else { + BUG_ON(lp->non_tagged_cmd != ent); +@@ -667,6 +667,8 @@ static struct esp_cmd_entry *find_and_prep_issuable_command(struct esp *esp) + ent->tag[0] = 0; + ent->tag[1] = 0; + } ++ ent->orig_tag[0] = ent->tag[0]; ++ ent->orig_tag[1] = ent->tag[1]; + + if (esp_alloc_lun_tag(ent, lp) < 0) + continue; +diff --git a/drivers/scsi/esp_scsi.h b/drivers/scsi/esp_scsi.h +index 28e22ac..cd68805 100644 +--- a/drivers/scsi/esp_scsi.h ++++ b/drivers/scsi/esp_scsi.h +@@ -271,6 +271,7 @@ struct esp_cmd_entry { + #define ESP_CMD_FLAG_AUTOSENSE 0x04 /* Doing automatic REQUEST_SENSE */ + + u8 tag[2]; ++ u8 orig_tag[2]; + + u8 status; + u8 message; +diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c +index 403fc09..8b564ad 100644 +--- a/drivers/staging/comedi/drivers/ni_65xx.c ++++ b/drivers/staging/comedi/drivers/ni_65xx.c +@@ -411,29 +411,25 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) + { +- unsigned base_bitfield_channel; +- const unsigned max_ports_per_bitfield = 5; ++ int base_bitfield_channel; + unsigned read_bits = 0; +- unsigned j; ++ int last_port_offset = ni_65xx_port_by_channel(s->n_chan - 1); ++ int port_offset; ++ + if (insn->n != 2) + return -EINVAL; + base_bitfield_channel = CR_CHAN(insn->chanspec); +- for (j = 0; j < max_ports_per_bitfield; ++j) { +- const unsigned port_offset = +- ni_65xx_port_by_channel(base_bitfield_channel) + j; +- const unsigned port = +- sprivate(s)->base_port + port_offset; +- unsigned base_port_channel; ++ for (port_offset = ni_65xx_port_by_channel(base_bitfield_channel); ++ port_offset <= last_port_offset; port_offset++) { ++ unsigned port = sprivate(s)->base_port + port_offset; ++ int base_port_channel = port_offset * ni_65xx_channels_per_port; + unsigned port_mask, port_data, port_read_bits; +- int bitshift; +- if (port >= ni_65xx_total_num_ports(board(dev))) ++ int bitshift = base_port_channel - base_bitfield_channel; ++ ++ if (bitshift >= 32) + break; +- base_port_channel = port_offset * ni_65xx_channels_per_port; + port_mask = data[0]; + port_data = data[1]; +- bitshift = base_port_channel - base_bitfield_channel; +- if (bitshift >= 32 || bitshift <= -32) +- break; + if (bitshift > 0) { + port_mask >>= bitshift; + port_data >>= bitshift; +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index a37f14c..9def72f 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -81,6 +81,7 @@ static void option_instat_callback(struct urb *urb); + + #define HUAWEI_VENDOR_ID 0x12D1 + #define HUAWEI_PRODUCT_E173 0x140C ++#define HUAWEI_PRODUCT_E1750 0x1406 + #define HUAWEI_PRODUCT_K4505 0x1464 + #define HUAWEI_PRODUCT_K3765 0x1465 + #define HUAWEI_PRODUCT_K4605 0x14C6 +@@ -581,6 +582,8 @@ static const struct usb_device_id option_ids[] = { + { 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 }, ++ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1750, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t) &net_intf2_blacklist }, + { 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), +diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c +index 646ee21..92841a7 100644 +--- a/fs/btrfs/relocation.c ++++ b/fs/btrfs/relocation.c +@@ -684,6 +684,7 @@ struct backref_node *build_backref_tree(struct reloc_control *rc, + int cowonly; + int ret; + int err = 0; ++ bool need_check = true; + + path1 = btrfs_alloc_path(); + path2 = btrfs_alloc_path(); +@@ -906,6 +907,7 @@ again: + cur->bytenr); + + lower = cur; ++ need_check = true; + for (; level < BTRFS_MAX_LEVEL; level++) { + if (!path2->nodes[level]) { + BUG_ON(btrfs_root_bytenr(&root->root_item) != +@@ -949,14 +951,12 @@ again: + + /* + * add the block to pending list if we +- * need check its backrefs. only block +- * at 'cur->level + 1' is added to the +- * tail of pending list. this guarantees +- * we check backrefs from lower level +- * blocks to upper level blocks. ++ * need check its backrefs, we only do this once ++ * while walking up a tree as we will catch ++ * anything else later on. + */ +- if (!upper->checked && +- level == cur->level + 1) { ++ if (!upper->checked && need_check) { ++ need_check = false; + list_add_tail(&edge->list[UPPER], + &list); + } else +diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c +index 9fb3fae..54ad9a5 100644 +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -2054,7 +2054,8 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode) + int err = 0; + + /* ext4_handle_valid() assumes a valid handle_t pointer */ +- if (handle && !ext4_handle_valid(handle)) ++ if (handle && !ext4_handle_valid(handle) && ++ !(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ORPHAN_FS)) + return 0; + + mutex_lock(&EXT4_SB(inode->i_sb)->s_orphan_lock); +diff --git a/include/linux/mm.h b/include/linux/mm.h +index ece5ff4..dbca4b2 100644 +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -866,7 +866,8 @@ extern void pagefault_out_of_memory(void); + * Flags passed to show_mem() and show_free_areas() to suppress output in + * various contexts. + */ +-#define SHOW_MEM_FILTER_NODES (0x0001u) /* filter disallowed nodes */ ++#define SHOW_MEM_FILTER_NODES (0x0001u) /* disallowed nodes */ ++#define SHOW_MEM_FILTER_PAGE_COUNT (0x0002u) /* page type count */ + + extern void show_free_areas(unsigned int flags); + extern bool skip_free_areas_node(unsigned int flags, int nid); +diff --git a/include/net/ip.h b/include/net/ip.h +index b53d65f..0750bf7 100644 +--- a/include/net/ip.h ++++ b/include/net/ip.h +@@ -266,9 +266,11 @@ int ip_dont_fragment(struct sock *sk, struct dst_entry *dst) + + extern void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more); + +-static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, struct sock *sk) ++static inline void ip_select_ident(struct sk_buff *skb, struct dst_entry *dst, struct sock *sk) + { +- if (iph->frag_off & htons(IP_DF)) { ++ struct iphdr *iph = ip_hdr(skb); ++ ++ if ((iph->frag_off & htons(IP_DF)) && !skb->local_df) { + /* This is only to work around buggy Windows95/2000 + * VJ compression implementations. If the ID field + * does not change, they drop every other packet in +@@ -280,9 +282,11 @@ static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, str + __ip_select_ident(iph, dst, 0); + } + +-static inline void ip_select_ident_more(struct iphdr *iph, struct dst_entry *dst, struct sock *sk, int more) ++static inline void ip_select_ident_more(struct sk_buff *skb, struct dst_entry *dst, struct sock *sk, int more) + { +- if (iph->frag_off & htons(IP_DF)) { ++ struct iphdr *iph = ip_hdr(skb); ++ ++ if ((iph->frag_off & htons(IP_DF)) && !skb->local_df) { + if (sk && inet_sk(sk)->inet_daddr) { + iph->id = htons(inet_sk(sk)->inet_id); + inet_sk(sk)->inet_id += 1 + more; +diff --git a/include/net/ipip.h b/include/net/ipip.h +index a32654d..4dccfe3 100644 +--- a/include/net/ipip.h ++++ b/include/net/ipip.h +@@ -50,7 +50,7 @@ struct ip_tunnel_prl_entry { + int pkt_len = skb->len - skb_transport_offset(skb); \ + \ + skb->ip_summed = CHECKSUM_NONE; \ +- ip_select_ident(iph, &rt->dst, NULL); \ ++ ip_select_ident(skb, &rt->dst, NULL); \ + \ + err = ip_local_out(skb); \ + if (likely(net_xmit_eval(err) == 0)) { \ +diff --git a/lib/show_mem.c b/lib/show_mem.c +index 4407f8c..b7c7231 100644 +--- a/lib/show_mem.c ++++ b/lib/show_mem.c +@@ -18,6 +18,9 @@ void show_mem(unsigned int filter) + printk("Mem-Info:\n"); + show_free_areas(filter); + ++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT) ++ return; ++ + for_each_online_pgdat(pgdat) { + unsigned long i, flags; + +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index 8090542..508822e 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -1885,6 +1885,13 @@ void warn_alloc_failed(gfp_t gfp_mask, int order, const char *fmt, ...) + return; + + /* ++ * Walking all memory to count page types is very expensive and should ++ * be inhibited in non-blockable contexts. ++ */ ++ if (!(gfp_mask & __GFP_WAIT)) ++ filter |= SHOW_MEM_FILTER_PAGE_COUNT; ++ ++ /* + * This documents exceptions given to allocations in certain + * contexts that are allowed to allocate outside current's set + * of allowed nodes. +diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c +index ef45e10..1e6347c 100644 +--- a/net/bluetooth/hci_event.c ++++ b/net/bluetooth/hci_event.c +@@ -3375,7 +3375,11 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev, + cp.handle = cpu_to_le16(conn->handle); + + if (ltk->authenticated) +- conn->sec_level = BT_SECURITY_HIGH; ++ conn->pending_sec_level = BT_SECURITY_HIGH; ++ else ++ conn->pending_sec_level = BT_SECURITY_MEDIUM; ++ ++ conn->enc_key_size = ltk->enc_size; + + hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); + +diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h +index 51e8826..1237006 100644 +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -501,6 +501,7 @@ extern struct net_bridge_port *br_get_port(struct net_bridge *br, + extern void br_init_port(struct net_bridge_port *p); + extern void br_become_designated_port(struct net_bridge_port *p); + ++extern void __br_set_forward_delay(struct net_bridge *br, unsigned long t); + extern int br_set_forward_delay(struct net_bridge *br, unsigned long x); + extern int br_set_hello_time(struct net_bridge *br, unsigned long x); + extern int br_set_max_age(struct net_bridge *br, unsigned long x); +diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c +index 8c836d9..eca1c94 100644 +--- a/net/bridge/br_stp.c ++++ b/net/bridge/br_stp.c +@@ -189,7 +189,7 @@ static void br_record_config_information(struct net_bridge_port *p, + p->designated_age = jiffies - bpdu->message_age; + + mod_timer(&p->message_age_timer, jiffies +- + (p->br->max_age - bpdu->message_age)); ++ + (bpdu->max_age - bpdu->message_age)); + } + + /* called under bridge lock */ +@@ -517,18 +517,27 @@ int br_set_max_age(struct net_bridge *br, unsigned long val) + + } + ++void __br_set_forward_delay(struct net_bridge *br, unsigned long t) ++{ ++ br->bridge_forward_delay = t; ++ if (br_is_root_bridge(br)) ++ br->forward_delay = br->bridge_forward_delay; ++} ++ + int br_set_forward_delay(struct net_bridge *br, unsigned long val) + { + unsigned long t = clock_t_to_jiffies(val); ++ int err = -ERANGE; + ++ spin_lock_bh(&br->lock); + if (br->stp_enabled != BR_NO_STP && + (t < BR_MIN_FORWARD_DELAY || t > BR_MAX_FORWARD_DELAY)) +- return -ERANGE; ++ goto unlock; + +- spin_lock_bh(&br->lock); +- br->bridge_forward_delay = t; +- if (br_is_root_bridge(br)) +- br->forward_delay = br->bridge_forward_delay; ++ __br_set_forward_delay(br, t); ++ err = 0; ++ ++unlock: + spin_unlock_bh(&br->lock); +- return 0; ++ return err; + } +diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c +index f494496..f774796 100644 +--- a/net/bridge/br_stp_if.c ++++ b/net/bridge/br_stp_if.c +@@ -129,6 +129,14 @@ static void br_stp_start(struct net_bridge *br) + char *envp[] = { NULL }; + + r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC); ++ ++ spin_lock_bh(&br->lock); ++ ++ if (br->bridge_forward_delay < BR_MIN_FORWARD_DELAY) ++ __br_set_forward_delay(br, BR_MIN_FORWARD_DELAY); ++ else if (br->bridge_forward_delay < BR_MAX_FORWARD_DELAY) ++ __br_set_forward_delay(br, BR_MAX_FORWARD_DELAY); ++ + if (r == 0) { + br->stp_enabled = BR_USER_STP; + br_debug(br, "userspace STP started\n"); +@@ -137,10 +145,10 @@ static void br_stp_start(struct net_bridge *br) + br_debug(br, "using kernel STP\n"); + + /* To start timers on any ports left in blocking */ +- spin_lock_bh(&br->lock); + br_port_state_selection(br); +- spin_unlock_bh(&br->lock); + } ++ ++ spin_unlock_bh(&br->lock); + } + + static void br_stp_stop(struct net_bridge *br) +diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c +index 5cf5222..84efbe4 100644 +--- a/net/caif/cfctrl.c ++++ b/net/caif/cfctrl.c +@@ -288,9 +288,10 @@ int cfctrl_linkup_request(struct cflayer *layer, + + count = cfctrl_cancel_req(&cfctrl->serv.layer, + user_layer); +- if (count != 1) ++ if (count != 1) { + pr_err("Could not remove request (%d)", count); + return -ENODEV; ++ } + } + return 0; + } +diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c +index a225089..2774788 100644 +--- a/net/core/flow_dissector.c ++++ b/net/core/flow_dissector.c +@@ -133,8 +133,8 @@ ipv6: + if (poff >= 0) { + __be32 *ports, _ports; + +- nhoff += poff; +- ports = skb_header_pointer(skb, nhoff, sizeof(_ports), &_ports); ++ ports = skb_header_pointer(skb, nhoff + poff, ++ sizeof(_ports), &_ports); + if (ports) + flow->ports = *ports; + } +diff --git a/net/core/netpoll.c b/net/core/netpoll.c +index f9f40b9..5e81c49 100644 +--- a/net/core/netpoll.c ++++ b/net/core/netpoll.c +@@ -920,15 +920,14 @@ EXPORT_SYMBOL_GPL(__netpoll_cleanup); + + void netpoll_cleanup(struct netpoll *np) + { +- if (!np->dev) +- return; +- + rtnl_lock(); ++ if (!np->dev) ++ goto out; + __netpoll_cleanup(np); +- rtnl_unlock(); +- + dev_put(np->dev); + np->dev = NULL; ++out: ++ rtnl_unlock(); + } + EXPORT_SYMBOL(netpoll_cleanup); + +diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c +index 5dfecfd..c8e2699 100644 +--- a/net/ipv4/igmp.c ++++ b/net/ipv4/igmp.c +@@ -343,7 +343,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) + pip->saddr = fl4.saddr; + pip->protocol = IPPROTO_IGMP; + pip->tot_len = 0; /* filled in later */ +- ip_select_ident(pip, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + ((u8*)&pip[1])[0] = IPOPT_RA; + ((u8*)&pip[1])[1] = 4; + ((u8*)&pip[1])[2] = 0; +@@ -687,7 +687,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, + iph->daddr = dst; + iph->saddr = fl4.saddr; + iph->protocol = IPPROTO_IGMP; +- ip_select_ident(iph, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + ((u8*)&iph[1])[0] = IPOPT_RA; + ((u8*)&iph[1])[1] = 4; + ((u8*)&iph[1])[2] = 0; +@@ -709,7 +709,7 @@ static void igmp_gq_timer_expire(unsigned long data) + + in_dev->mr_gq_running = 0; + igmpv3_send_report(in_dev, NULL); +- __in_dev_put(in_dev); ++ in_dev_put(in_dev); + } + + static void igmp_ifc_timer_expire(unsigned long data) +@@ -721,7 +721,7 @@ static void igmp_ifc_timer_expire(unsigned long data) + in_dev->mr_ifc_count--; + igmp_ifc_start_timer(in_dev, IGMP_Unsolicited_Report_Interval); + } +- __in_dev_put(in_dev); ++ in_dev_put(in_dev); + } + + static void igmp_ifc_event(struct in_device *in_dev) +diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c +index dfba343..d63a926 100644 +--- a/net/ipv4/inetpeer.c ++++ b/net/ipv4/inetpeer.c +@@ -32,8 +32,8 @@ + * At the moment of writing this notes identifier of IP packets is generated + * to be unpredictable using this code only for packets subjected + * (actually or potentially) to defragmentation. I.e. DF packets less than +- * PMTU in size uses a constant ID and do not use this code (see +- * ip_select_ident() in include/net/ip.h). ++ * PMTU in size when local fragmentation is disabled use a constant ID and do ++ * not use this code (see ip_select_ident() in include/net/ip.h). + * + * Route cache entries hold references to our nodes. + * New cache entries get references via lookup by destination IP address in +diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c +index 4910176..3bc4c97 100644 +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -161,7 +161,7 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk, + iph->daddr = (opt && opt->opt.srr ? opt->opt.faddr : daddr); + iph->saddr = saddr; + iph->protocol = sk->sk_protocol; +- ip_select_ident(iph, &rt->dst, sk); ++ ip_select_ident(skb, &rt->dst, sk); + + if (opt && opt->opt.optlen) { + iph->ihl += opt->opt.optlen>>2; +@@ -403,7 +403,7 @@ packet_routed: + ip_options_build(skb, &inet_opt->opt, inet->inet_daddr, rt, 0); + } + +- ip_select_ident_more(iph, &rt->dst, sk, ++ ip_select_ident_more(skb, &rt->dst, sk, + (skb_shinfo(skb)->gso_segs ?: 1) - 1); + + skb->priority = sk->sk_priority; +@@ -1342,12 +1342,12 @@ struct sk_buff *__ip_make_skb(struct sock *sk, + else + ttl = ip_select_ttl(inet, &rt->dst); + +- iph = (struct iphdr *)skb->data; ++ iph = ip_hdr(skb); + iph->version = 4; + iph->ihl = 5; + iph->tos = inet->tos; + iph->frag_off = df; +- ip_select_ident(iph, &rt->dst, sk); ++ ip_select_ident(skb, &rt->dst, sk); + iph->ttl = ttl; + iph->protocol = sk->sk_protocol; + ip_copy_addrs(iph, fl4); +diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c +index 8626b64..a0b7166 100644 +--- a/net/ipv4/ipmr.c ++++ b/net/ipv4/ipmr.c +@@ -1573,7 +1573,7 @@ static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr) + iph->protocol = IPPROTO_IPIP; + iph->ihl = 5; + iph->tot_len = htons(skb->len); +- ip_select_ident(iph, skb_dst(skb), NULL); ++ ip_select_ident(skb, skb_dst(skb), NULL); + ip_send_check(iph); + + memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); +diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c +index 2fe0dc2..c6b9ca6 100644 +--- a/net/ipv4/raw.c ++++ b/net/ipv4/raw.c +@@ -384,7 +384,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4, + iph->check = 0; + iph->tot_len = htons(length); + if (!iph->id) +- ip_select_ident(iph, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + + iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); + } +diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c +index ed4bf11..938553e 100644 +--- a/net/ipv4/xfrm4_mode_tunnel.c ++++ b/net/ipv4/xfrm4_mode_tunnel.c +@@ -54,7 +54,7 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) + + top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ? + 0 : (XFRM_MODE_SKB_CB(skb)->frag_off & htons(IP_DF)); +- ip_select_ident(top_iph, dst->child, NULL); ++ ip_select_ident(skb, dst->child, NULL); + + top_iph->ttl = ip4_dst_hoplimit(dst->child); + +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index d6b9d56..1acfb19 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -1128,6 +1128,8 @@ static inline int ip6_ufo_append_data(struct sock *sk, + * udp datagram + */ + if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) { ++ struct frag_hdr fhdr; ++ + skb = sock_alloc_send_skb(sk, + hh_len + fragheaderlen + transhdrlen + 20, + (flags & MSG_DONTWAIT), &err); +@@ -1148,12 +1150,6 @@ static inline int ip6_ufo_append_data(struct sock *sk, + + skb->ip_summed = CHECKSUM_PARTIAL; + skb->csum = 0; +- } +- +- err = skb_append_datato_frags(sk,skb, getfrag, from, +- (length - transhdrlen)); +- if (!err) { +- struct frag_hdr fhdr; + + /* Specify the length of each IPv6 datagram fragment. + * It has to be a multiple of 8. +@@ -1164,15 +1160,10 @@ static inline int ip6_ufo_append_data(struct sock *sk, + ipv6_select_ident(&fhdr, rt); + skb_shinfo(skb)->ip6_frag_id = fhdr.identification; + __skb_queue_tail(&sk->sk_write_queue, skb); +- +- return 0; + } +- /* There is not enough support do UPD LSO, +- * so follow normal path +- */ +- kfree_skb(skb); + +- return err; ++ return skb_append_datato_frags(sk, skb, getfrag, from, ++ (length - transhdrlen)); + } + + static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src, +@@ -1345,27 +1336,27 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, + * --yoshfuji + */ + +- cork->length += length; +- if (length > mtu) { +- int proto = sk->sk_protocol; +- if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW)){ +- ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen); +- return -EMSGSIZE; +- } +- +- if (proto == IPPROTO_UDP && +- (rt->dst.dev->features & NETIF_F_UFO)) { ++ if ((length > mtu) && dontfrag && (sk->sk_protocol == IPPROTO_UDP || ++ sk->sk_protocol == IPPROTO_RAW)) { ++ ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen); ++ return -EMSGSIZE; ++ } + +- err = ip6_ufo_append_data(sk, getfrag, from, length, +- hh_len, fragheaderlen, +- transhdrlen, mtu, flags, rt); +- if (err) +- goto error; +- return 0; +- } ++ skb = skb_peek_tail(&sk->sk_write_queue); ++ cork->length += length; ++ if (((length > mtu) || ++ (skb && skb_is_gso(skb))) && ++ (sk->sk_protocol == IPPROTO_UDP) && ++ (rt->dst.dev->features & NETIF_F_UFO)) { ++ err = ip6_ufo_append_data(sk, getfrag, from, length, ++ hh_len, fragheaderlen, ++ transhdrlen, mtu, flags, rt); ++ if (err) ++ goto error; ++ return 0; + } + +- if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) ++ if (!skb) + goto alloc_new_skb; + + while (length > 0) { +diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c +index 6a4ab24..9728df5 100644 +--- a/net/ipv6/mcast.c ++++ b/net/ipv6/mcast.c +@@ -2149,7 +2149,7 @@ static void mld_gq_timer_expire(unsigned long data) + + idev->mc_gq_running = 0; + mld_send_report(idev, NULL); +- __in6_dev_put(idev); ++ in6_dev_put(idev); + } + + static void mld_ifc_timer_expire(unsigned long data) +@@ -2162,7 +2162,7 @@ static void mld_ifc_timer_expire(unsigned long data) + if (idev->mc_ifc_count) + mld_ifc_start_timer(idev, idev->mc_maxdelay); + } +- __in6_dev_put(idev); ++ in6_dev_put(idev); + } + + static void mld_ifc_event(struct inet6_dev *idev) +diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c +index 7fd66de..ec78ab6 100644 +--- a/net/netfilter/ipvs/ip_vs_xmit.c ++++ b/net/netfilter/ipvs/ip_vs_xmit.c +@@ -853,7 +853,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, + iph->daddr = cp->daddr.ip; + iph->saddr = saddr; + iph->ttl = old_iph->ttl; +- ip_select_ident(iph, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + + /* Another hack: avoid icmp_send in ip_fragment */ + skb->local_df = 1; +diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c +index 91f4791..53a7f03 100644 +--- a/net/sctp/ipv6.c ++++ b/net/sctp/ipv6.c +@@ -205,45 +205,24 @@ out: + in6_dev_put(idev); + } + +-/* Based on tcp_v6_xmit() in tcp_ipv6.c. */ + static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport) + { + struct sock *sk = skb->sk; + struct ipv6_pinfo *np = inet6_sk(sk); +- struct flowi6 fl6; +- +- memset(&fl6, 0, sizeof(fl6)); +- +- fl6.flowi6_proto = sk->sk_protocol; +- +- /* Fill in the dest address from the route entry passed with the skb +- * and the source address from the transport. +- */ +- fl6.daddr = transport->ipaddr.v6.sin6_addr; +- fl6.saddr = transport->saddr.v6.sin6_addr; +- +- fl6.flowlabel = np->flow_label; +- IP6_ECN_flow_xmit(sk, fl6.flowlabel); +- if (ipv6_addr_type(&fl6.saddr) & IPV6_ADDR_LINKLOCAL) +- fl6.flowi6_oif = transport->saddr.v6.sin6_scope_id; +- else +- fl6.flowi6_oif = sk->sk_bound_dev_if; +- +- if (np->opt && np->opt->srcrt) { +- struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; +- fl6.daddr = *rt0->addr; +- } ++ struct flowi6 *fl6 = &transport->fl.u.ip6; + + SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n", + __func__, skb, skb->len, +- &fl6.saddr, &fl6.daddr); ++ &fl6->saddr, &fl6->daddr); + +- SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS); ++ IP6_ECN_flow_xmit(sk, fl6->flowlabel); + + if (!(transport->param_flags & SPP_PMTUD_ENABLE)) + skb->local_df = 1; + +- return ip6_xmit(sk, skb, &fl6, np->opt, np->tclass); ++ SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS); ++ ++ return ip6_xmit(sk, skb, fl6, np->opt, np->tclass); + } + + /* Returns the dst cache entry for the given source and destination ip +@@ -256,10 +235,12 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, + struct dst_entry *dst = NULL; + struct flowi6 *fl6 = &fl->u.ip6; + struct sctp_bind_addr *bp; ++ struct ipv6_pinfo *np = inet6_sk(sk); + struct sctp_sockaddr_entry *laddr; + union sctp_addr *baddr = NULL; + union sctp_addr *daddr = &t->ipaddr; + union sctp_addr dst_saddr; ++ struct in6_addr *final_p, final; + __u8 matchlen = 0; + __u8 bmatchlen; + sctp_scope_t scope; +@@ -282,7 +263,8 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, + SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl6->saddr); + } + +- dst = ip6_dst_lookup_flow(sk, fl6, NULL, false); ++ final_p = fl6_update_dst(fl6, np->opt, &final); ++ dst = ip6_dst_lookup_flow(sk, fl6, final_p, false); + if (!asoc || saddr) + goto out; + +@@ -333,10 +315,12 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, + } + } + rcu_read_unlock(); ++ + if (baddr) { + fl6->saddr = baddr->v6.sin6_addr; + fl6->fl6_sport = baddr->v6.sin6_port; +- dst = ip6_dst_lookup_flow(sk, fl6, NULL, false); ++ final_p = fl6_update_dst(fl6, np->opt, &final); ++ dst = ip6_dst_lookup_flow(sk, fl6, final_p, false); + } + + out: +diff --git a/net/sctp/socket.c b/net/sctp/socket.c +index 4bc6e0b..e9e50ca 100644 +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -814,6 +814,9 @@ static int sctp_send_asconf_del_ip(struct sock *sk, + goto skip_mkasconf; + } + ++ if (laddr == NULL) ++ return -EINVAL; ++ + /* We do not need RCU protection throughout this loop + * because this is done under a socket lock from the + * setsockopt call. +diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c +index 9fd3b68..3ff2b94 100644 +--- a/sound/soc/codecs/88pm860x-codec.c ++++ b/sound/soc/codecs/88pm860x-codec.c +@@ -351,6 +351,9 @@ static int snd_soc_put_volsw_2r_st(struct snd_kcontrol *kcontrol, + val = ucontrol->value.integer.value[0]; + val2 = ucontrol->value.integer.value[1]; + ++ if (val >= ARRAY_SIZE(st_table) || val2 >= ARRAY_SIZE(st_table)) ++ return -EINVAL; ++ + err = snd_soc_update_bits(codec, reg, 0x3f, st_table[val].m); + if (err < 0) + return err; +diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c +index 0bb511a..196dfa3 100644 +--- a/sound/soc/codecs/max98095.c ++++ b/sound/soc/codecs/max98095.c +@@ -1860,7 +1860,7 @@ static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol, + struct max98095_pdata *pdata = max98095->pdata; + int channel = max98095_get_eq_channel(kcontrol->id.name); + struct max98095_cdata *cdata; +- int sel = ucontrol->value.integer.value[0]; ++ unsigned int sel = ucontrol->value.integer.value[0]; + struct max98095_eq_cfg *coef_set; + int fs, best, best_val, i; + int regmask, regsave; +@@ -2013,7 +2013,7 @@ static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol, + struct max98095_pdata *pdata = max98095->pdata; + int channel = max98095_get_bq_channel(codec, kcontrol->id.name); + struct max98095_cdata *cdata; +- int sel = ucontrol->value.integer.value[0]; ++ unsigned int sel = ucontrol->value.integer.value[0]; + struct max98095_biquad_cfg *coef_set; + int fs, best, best_val, i; + int regmask, regsave; diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.66-67.patch b/patch/kernel/sun8i-default/0001-patch-3.4.66-67.patch new file mode 100644 index 000000000..4c439ffd4 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.66-67.patch @@ -0,0 +1,347 @@ +diff --git a/Makefile b/Makefile +index e9587ab..9f440dd 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 66 ++SUBLEVEL = 67 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c +index 45ba99f..71d7d72 100644 +--- a/arch/parisc/kernel/traps.c ++++ b/arch/parisc/kernel/traps.c +@@ -810,14 +810,14 @@ void notrace handle_interruption(int code, struct pt_regs *regs) + else { + + /* +- * The kernel should never fault on its own address space. ++ * The kernel should never fault on its own address space, ++ * unless pagefault_disable() was called before. + */ + +- if (fault_space == 0) ++ if (fault_space == 0 && !in_atomic()) + { + pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC); + parisc_terminate("Kernel Fault", regs, code, fault_address); +- + } + } + +diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S +index 24b23a4..126f38d 100644 +--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S ++++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S +@@ -935,7 +935,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) + BEGIN_FTR_SECTION + mfspr r8, SPRN_DSCR + ld r7, HSTATE_DSCR(r13) +- std r8, VCPU_DSCR(r7) ++ std r8, VCPU_DSCR(r9) + mtspr SPRN_DSCR, r7 + END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) + +diff --git a/drivers/char/random.c b/drivers/char/random.c +index d98b2a6..817eeb6 100644 +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -1435,12 +1435,11 @@ ctl_table random_table[] = { + + static u32 random_int_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; + +-static int __init random_int_secret_init(void) ++int random_int_secret_init(void) + { + get_random_bytes(random_int_secret, sizeof(random_int_secret)); + return 0; + } +-late_initcall(random_int_secret_init); + + /* + * Get a random word for internal kernel use only. Similar to urandom but +diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c +index 15d1f08..ad72295 100644 +--- a/drivers/gpu/drm/radeon/evergreen.c ++++ b/drivers/gpu/drm/radeon/evergreen.c +@@ -1912,7 +1912,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) + rdev->config.evergreen.sx_max_export_size = 256; + rdev->config.evergreen.sx_max_export_pos_size = 64; + rdev->config.evergreen.sx_max_export_smx_size = 192; +- rdev->config.evergreen.max_hw_contexts = 8; ++ rdev->config.evergreen.max_hw_contexts = 4; + rdev->config.evergreen.sq_num_cf_insts = 2; + + rdev->config.evergreen.sc_prim_fifo_size = 0x40; +diff --git a/drivers/watchdog/ts72xx_wdt.c b/drivers/watchdog/ts72xx_wdt.c +index 8df050d..1c53745 100644 +--- a/drivers/watchdog/ts72xx_wdt.c ++++ b/drivers/watchdog/ts72xx_wdt.c +@@ -310,7 +310,8 @@ static long ts72xx_wdt_ioctl(struct file *file, unsigned int cmd, + + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: +- return put_user(0, p); ++ error = put_user(0, p); ++ break; + + case WDIOC_KEEPALIVE: + ts72xx_wdt_kick(wdt); +diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c +index e712a8c..b1aa7fd 100644 +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -1268,6 +1268,8 @@ retry: + s_min_extra_isize) { + tried_min_extra_isize++; + new_extra_isize = s_min_extra_isize; ++ kfree(is); is = NULL; ++ kfree(bs); bs = NULL; + goto retry; + } + error = -1; +diff --git a/fs/statfs.c b/fs/statfs.c +index 43e6b6f..d1812b2 100644 +--- a/fs/statfs.c ++++ b/fs/statfs.c +@@ -87,7 +87,7 @@ int user_statfs(const char __user *pathname, struct kstatfs *st) + + int fd_statfs(int fd, struct kstatfs *st) + { +- struct file *file = fget(fd); ++ struct file *file = fget_raw(fd); + int error = -EBADF; + if (file) { + error = vfs_statfs(&file->f_path, st); +diff --git a/include/linux/random.h b/include/linux/random.h +index ac621ce..7e58ad2 100644 +--- a/include/linux/random.h ++++ b/include/linux/random.h +@@ -56,6 +56,7 @@ extern void add_interrupt_randomness(int irq, int irq_flags); + extern void get_random_bytes(void *buf, int nbytes); + extern void get_random_bytes_arch(void *buf, int nbytes); + void generate_random_uuid(unsigned char uuid_out[16]); ++extern int random_int_secret_init(void); + + #ifndef MODULE + extern const struct file_operations random_fops, urandom_fops; +diff --git a/init/main.c b/init/main.c +index 02c1384..db8e381 100644 +--- a/init/main.c ++++ b/init/main.c +@@ -68,6 +68,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -779,6 +780,7 @@ static void __init do_basic_setup(void) + do_ctors(); + usermodehelper_enable(); + do_initcalls(); ++ random_int_secret_init(); + } + + static void __init do_pre_smp_initcalls(void) +diff --git a/mm/mmap.c b/mm/mmap.c +index ed884dd..69367e4 100644 +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -6,6 +6,7 @@ + * Address space accounting code + */ + ++#include + #include + #include + #include +@@ -392,6 +393,34 @@ find_vma_prepare(struct mm_struct *mm, unsigned long addr, + return vma; + } + ++static unsigned long count_vma_pages_range(struct mm_struct *mm, ++ unsigned long addr, unsigned long end) ++{ ++ unsigned long nr_pages = 0; ++ struct vm_area_struct *vma; ++ ++ /* Find first overlaping mapping */ ++ vma = find_vma_intersection(mm, addr, end); ++ if (!vma) ++ return 0; ++ ++ nr_pages = (min(end, vma->vm_end) - ++ max(addr, vma->vm_start)) >> PAGE_SHIFT; ++ ++ /* Iterate over the rest of the overlaps */ ++ for (vma = vma->vm_next; vma; vma = vma->vm_next) { ++ unsigned long overlap_len; ++ ++ if (vma->vm_start > end) ++ break; ++ ++ overlap_len = min(end, vma->vm_end) - vma->vm_start; ++ nr_pages += overlap_len >> PAGE_SHIFT; ++ } ++ ++ return nr_pages; ++} ++ + void __vma_link_rb(struct mm_struct *mm, struct vm_area_struct *vma, + struct rb_node **rb_link, struct rb_node *rb_parent) + { +@@ -1245,6 +1274,23 @@ unsigned long mmap_region(struct file *file, unsigned long addr, + unsigned long charged = 0; + struct inode *inode = file ? file->f_path.dentry->d_inode : NULL; + ++ /* Check against address space limit. */ ++ if (!may_expand_vm(mm, len >> PAGE_SHIFT)) { ++ unsigned long nr_pages; ++ ++ /* ++ * MAP_FIXED may remove pages of mappings that intersects with ++ * requested mapping. Account for the pages it would unmap. ++ */ ++ if (!(vm_flags & MAP_FIXED)) ++ return -ENOMEM; ++ ++ nr_pages = count_vma_pages_range(mm, addr, addr + len); ++ ++ if (!may_expand_vm(mm, (len >> PAGE_SHIFT) - nr_pages)) ++ return -ENOMEM; ++ } ++ + /* Clear old maps */ + error = -ENOMEM; + munmap_back: +@@ -1255,10 +1301,6 @@ munmap_back: + goto munmap_back; + } + +- /* Check against address space limit. */ +- if (!may_expand_vm(mm, len >> PAGE_SHIFT)) +- return -ENOMEM; +- + /* + * Set 'VM_NORESERVE' if we should not account for the + * memory use of this mapping. +@@ -1833,9 +1875,28 @@ int expand_downwards(struct vm_area_struct *vma, + return error; + } + ++/* ++ * Note how expand_stack() refuses to expand the stack all the way to ++ * abut the next virtual mapping, *unless* that mapping itself is also ++ * a stack mapping. We want to leave room for a guard page, after all ++ * (the guard page itself is not added here, that is done by the ++ * actual page faulting logic) ++ * ++ * This matches the behavior of the guard page logic (see mm/memory.c: ++ * check_stack_guard_page()), which only allows the guard page to be ++ * removed under these circumstances. ++ */ + #ifdef CONFIG_STACK_GROWSUP + int expand_stack(struct vm_area_struct *vma, unsigned long address) + { ++ struct vm_area_struct *next; ++ ++ address &= PAGE_MASK; ++ next = vma->vm_next; ++ if (next && next->vm_start == address + PAGE_SIZE) { ++ if (!(next->vm_flags & VM_GROWSUP)) ++ return -ENOMEM; ++ } + return expand_upwards(vma, address); + } + +@@ -1858,6 +1919,14 @@ find_extend_vma(struct mm_struct *mm, unsigned long addr) + #else + int expand_stack(struct vm_area_struct *vma, unsigned long address) + { ++ struct vm_area_struct *prev; ++ ++ address &= PAGE_MASK; ++ prev = vma->vm_prev; ++ if (prev && prev->vm_end == address) { ++ if (!(prev->vm_flags & VM_GROWSDOWN)) ++ return -ENOMEM; ++ } + return expand_downwards(vma, address); + } + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 353b32a..33abb78 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -6832,6 +6832,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { + SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), + SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), + SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), ++ SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_ASUS_MODE4), + SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), + SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), + SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), +diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c +index 520ef96..711299c 100644 +--- a/sound/usb/usx2y/usbusx2yaudio.c ++++ b/sound/usb/usx2y/usbusx2yaudio.c +@@ -295,19 +295,6 @@ static void usX2Y_error_urb_status(struct usX2Ydev *usX2Y, + usX2Y_clients_stop(usX2Y); + } + +-static void usX2Y_error_sequence(struct usX2Ydev *usX2Y, +- struct snd_usX2Y_substream *subs, struct urb *urb) +-{ +- snd_printk(KERN_ERR +-"Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n" +-"Most probably some urb of usb-frame %i is still missing.\n" +-"Cause could be too long delays in usb-hcd interrupt handling.\n", +- usb_get_current_frame_number(usX2Y->dev), +- subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", +- usX2Y->wait_iso_frame, urb->start_frame, usX2Y->wait_iso_frame); +- usX2Y_clients_stop(usX2Y); +-} +- + static void i_usX2Y_urb_complete(struct urb *urb) + { + struct snd_usX2Y_substream *subs = urb->context; +@@ -324,12 +311,9 @@ static void i_usX2Y_urb_complete(struct urb *urb) + usX2Y_error_urb_status(usX2Y, subs, urb); + return; + } +- if (likely((urb->start_frame & 0xFFFF) == (usX2Y->wait_iso_frame & 0xFFFF))) +- subs->completed_urb = urb; +- else { +- usX2Y_error_sequence(usX2Y, subs, urb); +- return; +- } ++ ++ subs->completed_urb = urb; ++ + { + struct snd_usX2Y_substream *capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE], + *playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]; +diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c +index 8e40b6e..1da1eca 100644 +--- a/sound/usb/usx2y/usx2yhwdeppcm.c ++++ b/sound/usb/usx2y/usx2yhwdeppcm.c +@@ -244,13 +244,8 @@ static void i_usX2Y_usbpcm_urb_complete(struct urb *urb) + usX2Y_error_urb_status(usX2Y, subs, urb); + return; + } +- if (likely((urb->start_frame & 0xFFFF) == (usX2Y->wait_iso_frame & 0xFFFF))) +- subs->completed_urb = urb; +- else { +- usX2Y_error_sequence(usX2Y, subs, urb); +- return; +- } + ++ subs->completed_urb = urb; + capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE]; + capsubs2 = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2]; + playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]; diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.67-68.patch b/patch/kernel/sun8i-default/0001-patch-3.4.67-68.patch new file mode 100644 index 000000000..b18cbdf48 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.67-68.patch @@ -0,0 +1,1156 @@ +diff --git a/Makefile b/Makefile +index 9f440dd8256c..656c45f09128 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 67 ++SUBLEVEL = 68 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c +index 77e1e6cd66ce..2894461e0bdb 100644 +--- a/drivers/connector/cn_proc.c ++++ b/drivers/connector/cn_proc.c +@@ -64,6 +64,7 @@ void proc_fork_connector(struct task_struct *task) + + msg = (struct cn_msg*)buffer; + ev = (struct proc_event*)msg->data; ++ memset(&ev->event_data, 0, sizeof(ev->event_data)); + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ + put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); +@@ -79,6 +80,7 @@ void proc_fork_connector(struct task_struct *task) + memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); + msg->ack = 0; /* not used */ + msg->len = sizeof(*ev); ++ msg->flags = 0; /* not used */ + /* If cn_netlink_send() failed, the data is not sent */ + cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); + } +@@ -95,6 +97,7 @@ void proc_exec_connector(struct task_struct *task) + + msg = (struct cn_msg*)buffer; + ev = (struct proc_event*)msg->data; ++ memset(&ev->event_data, 0, sizeof(ev->event_data)); + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ + put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); +@@ -105,6 +108,7 @@ void proc_exec_connector(struct task_struct *task) + memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); + msg->ack = 0; /* not used */ + msg->len = sizeof(*ev); ++ msg->flags = 0; /* not used */ + cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); + } + +@@ -121,6 +125,7 @@ void proc_id_connector(struct task_struct *task, int which_id) + + msg = (struct cn_msg*)buffer; + ev = (struct proc_event*)msg->data; ++ memset(&ev->event_data, 0, sizeof(ev->event_data)); + ev->what = which_id; + ev->event_data.id.process_pid = task->pid; + ev->event_data.id.process_tgid = task->tgid; +@@ -144,6 +149,7 @@ void proc_id_connector(struct task_struct *task, int which_id) + memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); + msg->ack = 0; /* not used */ + msg->len = sizeof(*ev); ++ msg->flags = 0; /* not used */ + cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); + } + +@@ -159,6 +165,7 @@ void proc_sid_connector(struct task_struct *task) + + msg = (struct cn_msg *)buffer; + ev = (struct proc_event *)msg->data; ++ memset(&ev->event_data, 0, sizeof(ev->event_data)); + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ + put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); +@@ -169,6 +176,7 @@ void proc_sid_connector(struct task_struct *task) + memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); + msg->ack = 0; /* not used */ + msg->len = sizeof(*ev); ++ msg->flags = 0; /* not used */ + cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); + } + +@@ -184,6 +192,7 @@ void proc_ptrace_connector(struct task_struct *task, int ptrace_id) + + msg = (struct cn_msg *)buffer; + ev = (struct proc_event *)msg->data; ++ memset(&ev->event_data, 0, sizeof(ev->event_data)); + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ + put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); +@@ -202,6 +211,7 @@ void proc_ptrace_connector(struct task_struct *task, int ptrace_id) + memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); + msg->ack = 0; /* not used */ + msg->len = sizeof(*ev); ++ msg->flags = 0; /* not used */ + cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); + } + +@@ -217,6 +227,7 @@ void proc_comm_connector(struct task_struct *task) + + msg = (struct cn_msg *)buffer; + ev = (struct proc_event *)msg->data; ++ memset(&ev->event_data, 0, sizeof(ev->event_data)); + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ + put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); +@@ -228,6 +239,7 @@ void proc_comm_connector(struct task_struct *task) + memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); + msg->ack = 0; /* not used */ + msg->len = sizeof(*ev); ++ msg->flags = 0; /* not used */ + cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); + } + +@@ -243,6 +255,7 @@ void proc_exit_connector(struct task_struct *task) + + msg = (struct cn_msg*)buffer; + ev = (struct proc_event*)msg->data; ++ memset(&ev->event_data, 0, sizeof(ev->event_data)); + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ + put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); +@@ -255,6 +268,7 @@ void proc_exit_connector(struct task_struct *task) + memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); + msg->ack = 0; /* not used */ + msg->len = sizeof(*ev); ++ msg->flags = 0; /* not used */ + cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); + } + +@@ -278,6 +292,7 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack) + + msg = (struct cn_msg*)buffer; + ev = (struct proc_event*)msg->data; ++ memset(&ev->event_data, 0, sizeof(ev->event_data)); + msg->seq = rcvd_seq; + ktime_get_ts(&ts); /* get high res monotonic timestamp */ + put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); +@@ -287,6 +302,7 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack) + memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); + msg->ack = rcvd_ack + 1; + msg->len = sizeof(*ev); ++ msg->flags = 0; /* not used */ + cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); + } + +diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c +index dde6a0fad408..ea6efe86468e 100644 +--- a/drivers/connector/connector.c ++++ b/drivers/connector/connector.c +@@ -157,17 +157,18 @@ static int cn_call_callback(struct sk_buff *skb) + static void cn_rx_skb(struct sk_buff *__skb) + { + struct nlmsghdr *nlh; +- int err; + struct sk_buff *skb; ++ int len, err; + + skb = skb_get(__skb); + + if (skb->len >= NLMSG_SPACE(0)) { + nlh = nlmsg_hdr(skb); ++ len = nlmsg_len(nlh); + +- if (nlh->nlmsg_len < sizeof(struct cn_msg) || ++ if (len < (int)sizeof(struct cn_msg) || + skb->len < nlh->nlmsg_len || +- nlh->nlmsg_len > CONNECTOR_MAX_MSG_SIZE) { ++ len > CONNECTOR_MAX_MSG_SIZE) { + kfree_skb(skb); + return; + } +diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c +index 4caa8e6d59d7..2d2b1b7588d7 100644 +--- a/drivers/md/dm-snap-persistent.c ++++ b/drivers/md/dm-snap-persistent.c +@@ -269,6 +269,14 @@ static chunk_t area_location(struct pstore *ps, chunk_t area) + return NUM_SNAPSHOT_HDR_CHUNKS + ((ps->exceptions_per_area + 1) * area); + } + ++static void skip_metadata(struct pstore *ps) ++{ ++ uint32_t stride = ps->exceptions_per_area + 1; ++ chunk_t next_free = ps->next_free; ++ if (sector_div(next_free, stride) == NUM_SNAPSHOT_HDR_CHUNKS) ++ ps->next_free++; ++} ++ + /* + * Read or write a metadata area. Remembering to skip the first + * chunk which holds the header. +@@ -502,6 +510,8 @@ static int read_exceptions(struct pstore *ps, + + ps->current_area--; + ++ skip_metadata(ps); ++ + return 0; + } + +@@ -616,8 +626,6 @@ static int persistent_prepare_exception(struct dm_exception_store *store, + struct dm_exception *e) + { + struct pstore *ps = get_info(store); +- uint32_t stride; +- chunk_t next_free; + sector_t size = get_dev_size(dm_snap_cow(store->snap)->bdev); + + /* Is there enough room ? */ +@@ -630,10 +638,8 @@ static int persistent_prepare_exception(struct dm_exception_store *store, + * Move onto the next free pending, making sure to take + * into account the location of the metadata chunks. + */ +- stride = (ps->exceptions_per_area + 1); +- next_free = ++ps->next_free; +- if (sector_div(next_free, stride) == 1) +- ps->next_free++; ++ ps->next_free++; ++ skip_metadata(ps); + + atomic_inc(&ps->pending_count); + return 0; +diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c +index e86f4c37f981..c2cdefa1651e 100644 +--- a/drivers/net/can/dev.c ++++ b/drivers/net/can/dev.c +@@ -665,14 +665,14 @@ static size_t can_get_size(const struct net_device *dev) + size_t size; + + size = nla_total_size(sizeof(u32)); /* IFLA_CAN_STATE */ +- size += sizeof(struct can_ctrlmode); /* IFLA_CAN_CTRLMODE */ ++ size += nla_total_size(sizeof(struct can_ctrlmode)); /* IFLA_CAN_CTRLMODE */ + size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */ +- size += sizeof(struct can_bittiming); /* IFLA_CAN_BITTIMING */ +- size += sizeof(struct can_clock); /* IFLA_CAN_CLOCK */ ++ size += nla_total_size(sizeof(struct can_bittiming)); /* IFLA_CAN_BITTIMING */ ++ size += nla_total_size(sizeof(struct can_clock)); /* IFLA_CAN_CLOCK */ + if (priv->do_get_berr_counter) /* IFLA_CAN_BERR_COUNTER */ +- size += sizeof(struct can_berr_counter); ++ size += nla_total_size(sizeof(struct can_berr_counter)); + if (priv->bittiming_const) /* IFLA_CAN_BITTIMING_CONST */ +- size += sizeof(struct can_bittiming_const); ++ size += nla_total_size(sizeof(struct can_bittiming_const)); + + return size; + } +diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +index acd824660367..e45b8b6d6848 100644 +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +@@ -547,6 +547,7 @@ static inline void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, + skb, cqe, cqe_idx)) { + if (tpa_info->parsing_flags & PARSING_FLAGS_VLAN) + __vlan_hwaccel_put_tag(skb, tpa_info->vlan_tag); ++ skb_record_rx_queue(skb, fp->rx_queue); + napi_gro_receive(&fp->napi, skb); + } else { + DP(NETIF_MSG_RX_STATUS, +diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c +index 5e1ca0f05090..ffa6a72dcc60 100644 +--- a/drivers/net/ethernet/marvell/mv643xx_eth.c ++++ b/drivers/net/ethernet/marvell/mv643xx_eth.c +@@ -1274,15 +1274,13 @@ static void mib_counters_update(struct mv643xx_eth_private *mp) + p->rx_discard += rdlp(mp, RX_DISCARD_FRAME_CNT); + p->rx_overrun += rdlp(mp, RX_OVERRUN_FRAME_CNT); + spin_unlock_bh(&mp->mib_counters_lock); +- +- mod_timer(&mp->mib_counters_timer, jiffies + 30 * HZ); + } + + static void mib_counters_timer_wrapper(unsigned long _mp) + { + struct mv643xx_eth_private *mp = (void *)_mp; +- + mib_counters_update(mp); ++ mod_timer(&mp->mib_counters_timer, jiffies + 30 * HZ); + } + + +@@ -2370,6 +2368,7 @@ static int mv643xx_eth_open(struct net_device *dev) + mp->int_mask |= INT_TX_END_0 << i; + } + ++ add_timer(&mp->mib_counters_timer); + port_start(mp); + + wrlp(mp, INT_MASK_EXT, INT_EXT_LINK_PHY | INT_EXT_TX); +@@ -2911,7 +2910,6 @@ static int mv643xx_eth_probe(struct platform_device *pdev) + mp->mib_counters_timer.data = (unsigned long)mp; + mp->mib_counters_timer.function = mib_counters_timer_wrapper; + mp->mib_counters_timer.expires = jiffies + 30 * HZ; +- add_timer(&mp->mib_counters_timer); + + spin_lock_init(&mp->mib_counters_lock); + +diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c +index 43fada572596..c336d36cf5ca 100644 +--- a/drivers/net/ethernet/ti/davinci_emac.c ++++ b/drivers/net/ethernet/ti/davinci_emac.c +@@ -875,8 +875,7 @@ static void emac_dev_mcast_set(struct net_device *ndev) + netdev_mc_count(ndev) > EMAC_DEF_MAX_MULTICAST_ADDRESSES) { + mbp_enable = (mbp_enable | EMAC_MBP_RXMCAST); + emac_add_mcast(priv, EMAC_ALL_MULTI_SET, NULL); +- } +- if (!netdev_mc_empty(ndev)) { ++ } else if (!netdev_mc_empty(ndev)) { + struct netdev_hw_addr *ha; + + mbp_enable = (mbp_enable | EMAC_MBP_RXMCAST); +diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c +index 1a623183cbe5..3710427c3fe1 100644 +--- a/drivers/net/wan/farsync.c ++++ b/drivers/net/wan/farsync.c +@@ -1972,6 +1972,7 @@ fst_get_iface(struct fst_card_info *card, struct fst_port_info *port, + } + + i = port->index; ++ memset(&sync, 0, sizeof(sync)); + sync.clock_rate = FST_RDL(card, portConfig[i].lineSpeed); + /* Lucky card and linux use same encoding here */ + sync.clock_type = FST_RDB(card, portConfig[i].internalClock) == +diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c +index feb7541b33fb..ccd496bf32d9 100644 +--- a/drivers/net/wan/wanxl.c ++++ b/drivers/net/wan/wanxl.c +@@ -355,6 +355,7 @@ static int wanxl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) + ifr->ifr_settings.size = size; /* data size wanted */ + return -ENOBUFS; + } ++ memset(&line, 0, sizeof(line)); + line.clock_type = get_status(port)->clocking; + line.clock_rate = 0; + line.loopback = 0; +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 9def72f018e0..b3440c66a995 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -457,6 +457,10 @@ static void option_instat_callback(struct urb *urb); + #define CHANGHONG_VENDOR_ID 0x2077 + #define CHANGHONG_PRODUCT_CH690 0x7001 + ++/* Inovia */ ++#define INOVIA_VENDOR_ID 0x20a6 ++#define INOVIA_SEW858 0x1105 ++ + /* some devices interfaces need special handling due to a number of reasons */ + enum option_blacklist_reason { + OPTION_BLACKLIST_NONE = 0, +@@ -1279,7 +1283,9 @@ static const struct usb_device_id option_ids[] = { + + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD145) }, +- { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD200) }, ++ { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD200), ++ .driver_info = (kernel_ulong_t)&net_intf6_blacklist ++ }, + { 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) }, +@@ -1367,6 +1373,7 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) }, + { 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(INOVIA_VENDOR_ID, INOVIA_SEW858) }, + { } /* Terminating entry */ + }; + MODULE_DEVICE_TABLE(usb, option_ids); +diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c +index a7492ba5371a..1b0430e00b75 100644 +--- a/drivers/usb/serial/ti_usb_3410_5052.c ++++ b/drivers/usb/serial/ti_usb_3410_5052.c +@@ -210,6 +210,7 @@ static struct usb_device_id ti_id_table_combined[19+2*TI_EXTRA_VID_PID_COUNT+1] + { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) }, + { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) }, + { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) }, ++ { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) }, + { USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) }, + { } + }; +diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c +index cc761ad8fa57..92490e9f85ca 100644 +--- a/fs/ext3/dir.c ++++ b/fs/ext3/dir.c +@@ -21,30 +21,15 @@ + * + */ + ++#include + #include "ext3.h" + + static unsigned char ext3_filetype_table[] = { + DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK + }; + +-static int ext3_readdir(struct file *, void *, filldir_t); + static int ext3_dx_readdir(struct file * filp, + void * dirent, filldir_t filldir); +-static int ext3_release_dir (struct inode * inode, +- struct file * filp); +- +-const struct file_operations ext3_dir_operations = { +- .llseek = generic_file_llseek, +- .read = generic_read_dir, +- .readdir = ext3_readdir, /* we take BKL. needed?*/ +- .unlocked_ioctl = ext3_ioctl, +-#ifdef CONFIG_COMPAT +- .compat_ioctl = ext3_compat_ioctl, +-#endif +- .fsync = ext3_sync_file, /* BKL held */ +- .release = ext3_release_dir, +-}; +- + + static unsigned char get_dtype(struct super_block *sb, int filetype) + { +@@ -55,6 +40,25 @@ static unsigned char get_dtype(struct super_block *sb, int filetype) + return (ext3_filetype_table[filetype]); + } + ++/** ++ * Check if the given dir-inode refers to an htree-indexed directory ++ * (or a directory which chould potentially get coverted to use htree ++ * indexing). ++ * ++ * Return 1 if it is a dx dir, 0 if not ++ */ ++static int is_dx_dir(struct inode *inode) ++{ ++ struct super_block *sb = inode->i_sb; ++ ++ if (EXT3_HAS_COMPAT_FEATURE(inode->i_sb, ++ EXT3_FEATURE_COMPAT_DIR_INDEX) && ++ ((EXT3_I(inode)->i_flags & EXT3_INDEX_FL) || ++ ((inode->i_size >> sb->s_blocksize_bits) == 1))) ++ return 1; ++ ++ return 0; ++} + + int ext3_check_dir_entry (const char * function, struct inode * dir, + struct ext3_dir_entry_2 * de, +@@ -94,18 +98,13 @@ static int ext3_readdir(struct file * filp, + unsigned long offset; + int i, stored; + struct ext3_dir_entry_2 *de; +- struct super_block *sb; + int err; + struct inode *inode = filp->f_path.dentry->d_inode; ++ struct super_block *sb = inode->i_sb; + int ret = 0; + int dir_has_error = 0; + +- sb = inode->i_sb; +- +- if (EXT3_HAS_COMPAT_FEATURE(inode->i_sb, +- EXT3_FEATURE_COMPAT_DIR_INDEX) && +- ((EXT3_I(inode)->i_flags & EXT3_INDEX_FL) || +- ((inode->i_size >> sb->s_blocksize_bits) == 1))) { ++ if (is_dx_dir(inode)) { + err = ext3_dx_readdir(filp, dirent, filldir); + if (err != ERR_BAD_DX_DIR) { + ret = err; +@@ -227,22 +226,87 @@ out: + return ret; + } + ++static inline int is_32bit_api(void) ++{ ++#ifdef CONFIG_COMPAT ++ return is_compat_task(); ++#else ++ return (BITS_PER_LONG == 32); ++#endif ++} ++ + /* + * These functions convert from the major/minor hash to an f_pos +- * value. ++ * value for dx directories + * +- * Currently we only use major hash numer. This is unfortunate, but +- * on 32-bit machines, the same VFS interface is used for lseek and +- * llseek, so if we use the 64 bit offset, then the 32-bit versions of +- * lseek/telldir/seekdir will blow out spectacularly, and from within +- * the ext2 low-level routine, we don't know if we're being called by +- * a 64-bit version of the system call or the 32-bit version of the +- * system call. Worse yet, NFSv2 only allows for a 32-bit readdir +- * cookie. Sigh. ++ * Upper layer (for example NFS) should specify FMODE_32BITHASH or ++ * FMODE_64BITHASH explicitly. On the other hand, we allow ext3 to be mounted ++ * directly on both 32-bit and 64-bit nodes, under such case, neither ++ * FMODE_32BITHASH nor FMODE_64BITHASH is specified. + */ +-#define hash2pos(major, minor) (major >> 1) +-#define pos2maj_hash(pos) ((pos << 1) & 0xffffffff) +-#define pos2min_hash(pos) (0) ++static inline loff_t hash2pos(struct file *filp, __u32 major, __u32 minor) ++{ ++ if ((filp->f_mode & FMODE_32BITHASH) || ++ (!(filp->f_mode & FMODE_64BITHASH) && is_32bit_api())) ++ return major >> 1; ++ else ++ return ((__u64)(major >> 1) << 32) | (__u64)minor; ++} ++ ++static inline __u32 pos2maj_hash(struct file *filp, loff_t pos) ++{ ++ if ((filp->f_mode & FMODE_32BITHASH) || ++ (!(filp->f_mode & FMODE_64BITHASH) && is_32bit_api())) ++ return (pos << 1) & 0xffffffff; ++ else ++ return ((pos >> 32) << 1) & 0xffffffff; ++} ++ ++static inline __u32 pos2min_hash(struct file *filp, loff_t pos) ++{ ++ if ((filp->f_mode & FMODE_32BITHASH) || ++ (!(filp->f_mode & FMODE_64BITHASH) && is_32bit_api())) ++ return 0; ++ else ++ return pos & 0xffffffff; ++} ++ ++/* ++ * Return 32- or 64-bit end-of-file for dx directories ++ */ ++static inline loff_t ext3_get_htree_eof(struct file *filp) ++{ ++ if ((filp->f_mode & FMODE_32BITHASH) || ++ (!(filp->f_mode & FMODE_64BITHASH) && is_32bit_api())) ++ return EXT3_HTREE_EOF_32BIT; ++ else ++ return EXT3_HTREE_EOF_64BIT; ++} ++ ++ ++/* ++ * ext3_dir_llseek() calls generic_file_llseek[_size]() to handle both ++ * non-htree and htree directories, where the "offset" is in terms ++ * of the filename hash value instead of the byte offset. ++ * ++ * Because we may return a 64-bit hash that is well beyond s_maxbytes, ++ * we need to pass the max hash as the maximum allowable offset in ++ * the htree directory case. ++ * ++ * NOTE: offsets obtained *before* ext3_set_inode_flag(dir, EXT3_INODE_INDEX) ++ * will be invalid once the directory was converted into a dx directory ++ */ ++loff_t ext3_dir_llseek(struct file *file, loff_t offset, int origin) ++{ ++ struct inode *inode = file->f_mapping->host; ++ int dx_dir = is_dx_dir(inode); ++ ++ if (likely(dx_dir)) ++ return generic_file_llseek_size(file, offset, origin, ++ ext3_get_htree_eof(file)); ++ else ++ return generic_file_llseek(file, offset, origin); ++} + + /* + * This structure holds the nodes of the red-black tree used to store +@@ -303,15 +367,16 @@ static void free_rb_tree_fname(struct rb_root *root) + } + + +-static struct dir_private_info *ext3_htree_create_dir_info(loff_t pos) ++static struct dir_private_info *ext3_htree_create_dir_info(struct file *filp, ++ loff_t pos) + { + struct dir_private_info *p; + + p = kzalloc(sizeof(struct dir_private_info), GFP_KERNEL); + if (!p) + return NULL; +- p->curr_hash = pos2maj_hash(pos); +- p->curr_minor_hash = pos2min_hash(pos); ++ p->curr_hash = pos2maj_hash(filp, pos); ++ p->curr_minor_hash = pos2min_hash(filp, pos); + return p; + } + +@@ -401,7 +466,7 @@ static int call_filldir(struct file * filp, void * dirent, + printk("call_filldir: called with null fname?!?\n"); + return 0; + } +- curr_pos = hash2pos(fname->hash, fname->minor_hash); ++ curr_pos = hash2pos(filp, fname->hash, fname->minor_hash); + while (fname) { + error = filldir(dirent, fname->name, + fname->name_len, curr_pos, +@@ -426,13 +491,13 @@ static int ext3_dx_readdir(struct file * filp, + int ret; + + if (!info) { +- info = ext3_htree_create_dir_info(filp->f_pos); ++ info = ext3_htree_create_dir_info(filp, filp->f_pos); + if (!info) + return -ENOMEM; + filp->private_data = info; + } + +- if (filp->f_pos == EXT3_HTREE_EOF) ++ if (filp->f_pos == ext3_get_htree_eof(filp)) + return 0; /* EOF */ + + /* Some one has messed with f_pos; reset the world */ +@@ -440,8 +505,8 @@ static int ext3_dx_readdir(struct file * filp, + free_rb_tree_fname(&info->root); + info->curr_node = NULL; + info->extra_fname = NULL; +- info->curr_hash = pos2maj_hash(filp->f_pos); +- info->curr_minor_hash = pos2min_hash(filp->f_pos); ++ info->curr_hash = pos2maj_hash(filp, filp->f_pos); ++ info->curr_minor_hash = pos2min_hash(filp, filp->f_pos); + } + + /* +@@ -473,7 +538,7 @@ static int ext3_dx_readdir(struct file * filp, + if (ret < 0) + return ret; + if (ret == 0) { +- filp->f_pos = EXT3_HTREE_EOF; ++ filp->f_pos = ext3_get_htree_eof(filp); + break; + } + info->curr_node = rb_first(&info->root); +@@ -493,7 +558,7 @@ static int ext3_dx_readdir(struct file * filp, + info->curr_minor_hash = fname->minor_hash; + } else { + if (info->next_hash == ~0) { +- filp->f_pos = EXT3_HTREE_EOF; ++ filp->f_pos = ext3_get_htree_eof(filp); + break; + } + info->curr_hash = info->next_hash; +@@ -512,3 +577,15 @@ static int ext3_release_dir (struct inode * inode, struct file * filp) + + return 0; + } ++ ++const struct file_operations ext3_dir_operations = { ++ .llseek = ext3_dir_llseek, ++ .read = generic_read_dir, ++ .readdir = ext3_readdir, ++ .unlocked_ioctl = ext3_ioctl, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = ext3_compat_ioctl, ++#endif ++ .fsync = ext3_sync_file, ++ .release = ext3_release_dir, ++}; +diff --git a/fs/ext3/ext3.h b/fs/ext3/ext3.h +index b6515fd7e56c..fe5bef7914ea 100644 +--- a/fs/ext3/ext3.h ++++ b/fs/ext3/ext3.h +@@ -920,7 +920,11 @@ struct dx_hash_info + u32 *seed; + }; + +-#define EXT3_HTREE_EOF 0x7fffffff ++ ++/* 32 and 64 bit signed EOF for dx directories */ ++#define EXT3_HTREE_EOF_32BIT ((1UL << (32 - 1)) - 1) ++#define EXT3_HTREE_EOF_64BIT ((1ULL << (64 - 1)) - 1) ++ + + /* + * Control parameters used by ext3_htree_next_block +diff --git a/fs/ext3/hash.c b/fs/ext3/hash.c +index d10231ddcf8a..ede315cdf126 100644 +--- a/fs/ext3/hash.c ++++ b/fs/ext3/hash.c +@@ -198,8 +198,8 @@ int ext3fs_dirhash(const char *name, int len, struct dx_hash_info *hinfo) + return -1; + } + hash = hash & ~1; +- if (hash == (EXT3_HTREE_EOF << 1)) +- hash = (EXT3_HTREE_EOF-1) << 1; ++ if (hash == (EXT3_HTREE_EOF_32BIT << 1)) ++ hash = (EXT3_HTREE_EOF_32BIT - 1) << 1; + hinfo->hash = hash; + hinfo->minor_hash = minor_hash; + return 0; +diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h +index dc4d49a0c07d..42b919c36da1 100644 +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -760,6 +760,16 @@ static inline int skb_cloned(const struct sk_buff *skb) + (atomic_read(&skb_shinfo(skb)->dataref) & SKB_DATAREF_MASK) != 1; + } + ++static inline int skb_unclone(struct sk_buff *skb, gfp_t pri) ++{ ++ might_sleep_if(pri & __GFP_WAIT); ++ ++ if (skb_cloned(skb)) ++ return pskb_expand_head(skb, 0, 0, pri); ++ ++ return 0; ++} ++ + /** + * skb_header_cloned - is the header a clone + * @skb: buffer to check +@@ -1198,6 +1208,11 @@ static inline int skb_pagelen(const struct sk_buff *skb) + return len + skb_headlen(skb); + } + ++static inline bool skb_has_frags(const struct sk_buff *skb) ++{ ++ return skb_shinfo(skb)->nr_frags; ++} ++ + /** + * __skb_fill_page_desc - initialise a paged fragment in an skb + * @skb: buffer containing fragment to be initialised +diff --git a/include/net/cipso_ipv4.h b/include/net/cipso_ipv4.h +index a7a683e30b64..a8c2ef6d3b93 100644 +--- a/include/net/cipso_ipv4.h ++++ b/include/net/cipso_ipv4.h +@@ -290,6 +290,7 @@ static inline int cipso_v4_validate(const struct sk_buff *skb, + unsigned char err_offset = 0; + u8 opt_len = opt[1]; + u8 opt_iter; ++ u8 tag_len; + + if (opt_len < 8) { + err_offset = 1; +@@ -302,11 +303,12 @@ static inline int cipso_v4_validate(const struct sk_buff *skb, + } + + for (opt_iter = 6; opt_iter < opt_len;) { +- if (opt[opt_iter + 1] > (opt_len - opt_iter)) { ++ tag_len = opt[opt_iter + 1]; ++ if ((tag_len == 0) || (opt[opt_iter + 1] > (opt_len - opt_iter))) { + err_offset = opt_iter + 1; + goto out; + } +- opt_iter += opt[opt_iter + 1]; ++ opt_iter += tag_len; + } + + out: +diff --git a/include/net/dst.h b/include/net/dst.h +index 8197eadca819..1efe71aad089 100644 +--- a/include/net/dst.h ++++ b/include/net/dst.h +@@ -464,10 +464,22 @@ static inline struct dst_entry *xfrm_lookup(struct net *net, + { + return dst_orig; + } ++ ++static inline struct xfrm_state *dst_xfrm(const struct dst_entry *dst) ++{ ++ return NULL; ++} ++ + #else + extern struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig, + const struct flowi *fl, struct sock *sk, + int flags); ++ ++/* skb attached with this dst needs transformation if dst->xfrm is valid */ ++static inline struct xfrm_state *dst_xfrm(const struct dst_entry *dst) ++{ ++ return dst->xfrm; ++} + #endif + + #endif /* _NET_DST_H */ +diff --git a/mm/page-writeback.c b/mm/page-writeback.c +index bc8465f579a8..3b15e2a147a2 100644 +--- a/mm/page-writeback.c ++++ b/mm/page-writeback.c +@@ -1072,11 +1072,11 @@ static unsigned long dirty_poll_interval(unsigned long dirty, + return 1; + } + +-static long bdi_max_pause(struct backing_dev_info *bdi, +- unsigned long bdi_dirty) ++static unsigned long bdi_max_pause(struct backing_dev_info *bdi, ++ unsigned long bdi_dirty) + { +- long bw = bdi->avg_write_bandwidth; +- long t; ++ unsigned long bw = bdi->avg_write_bandwidth; ++ unsigned long t; + + /* + * Limit pause time for small memory systems. If sleeping for too long +@@ -1088,7 +1088,7 @@ static long bdi_max_pause(struct backing_dev_info *bdi, + t = bdi_dirty / (1 + bw / roundup_pow_of_two(1 + HZ / 8)); + t++; + +- return min_t(long, t, MAX_PAUSE); ++ return min_t(unsigned long, t, MAX_PAUSE); + } + + static long bdi_min_pause(struct backing_dev_info *bdi, +diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c +index 50711368ad6a..7f046b4c06bc 100644 +--- a/net/8021q/vlan_netlink.c ++++ b/net/8021q/vlan_netlink.c +@@ -152,7 +152,7 @@ static size_t vlan_get_size(const struct net_device *dev) + struct vlan_dev_priv *vlan = vlan_dev_priv(dev); + + return nla_total_size(2) + /* IFLA_VLAN_ID */ +- sizeof(struct ifla_vlan_flags) + /* IFLA_VLAN_FLAGS */ ++ nla_total_size(sizeof(struct ifla_vlan_flags)) + /* IFLA_VLAN_FLAGS */ + vlan_qos_map_size(vlan->nr_ingress_mappings) + + vlan_qos_map_size(vlan->nr_egress_mappings); + } +diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c +index f774796f7e57..2f100ccef86f 100644 +--- a/net/bridge/br_stp_if.c ++++ b/net/bridge/br_stp_if.c +@@ -134,7 +134,7 @@ static void br_stp_start(struct net_bridge *br) + + if (br->bridge_forward_delay < BR_MIN_FORWARD_DELAY) + __br_set_forward_delay(br, BR_MIN_FORWARD_DELAY); +- else if (br->bridge_forward_delay < BR_MAX_FORWARD_DELAY) ++ else if (br->bridge_forward_delay > BR_MAX_FORWARD_DELAY) + __br_set_forward_delay(br, BR_MAX_FORWARD_DELAY); + + if (r == 0) { +diff --git a/net/compat.c b/net/compat.c +index 014e1c78ecc5..ee84d82d7287 100644 +--- a/net/compat.c ++++ b/net/compat.c +@@ -71,6 +71,8 @@ int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg) + __get_user(kmsg->msg_controllen, &umsg->msg_controllen) || + __get_user(kmsg->msg_flags, &umsg->msg_flags)) + return -EFAULT; ++ if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) ++ return -EINVAL; + kmsg->msg_name = compat_ptr(tmp1); + kmsg->msg_iov = compat_ptr(tmp2); + kmsg->msg_control = compat_ptr(tmp3); +diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c +index 984ec656b03b..4afcf31bdfeb 100644 +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -268,7 +268,7 @@ begintw: + } + if (unlikely(!INET_TW_MATCH(sk, net, hash, acookie, + saddr, daddr, ports, dif))) { +- sock_put(sk); ++ inet_twsk_put(inet_twsk(sk)); + goto begintw; + } + goto out; +diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c +index 3bc4c978d7ad..d6407b563fd8 100644 +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -846,7 +846,7 @@ static int __ip_append_data(struct sock *sk, + csummode = CHECKSUM_PARTIAL; + + cork->length += length; +- if (((length > mtu) || (skb && skb_is_gso(skb))) && ++ if (((length > mtu) || (skb && skb_has_frags(skb))) && + (sk->sk_protocol == IPPROTO_UDP) && + (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len) { + err = ip_ufo_append_data(sk, queue, getfrag, from, length, +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index 167ea10b521a..108c73d760df 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -2713,7 +2713,7 @@ static struct rtable *ip_route_output_slow(struct net *net, struct flowi4 *fl4) + RT_SCOPE_LINK); + goto make_route; + } +- if (fl4->saddr) { ++ if (!fl4->saddr) { + if (ipv4_is_multicast(fl4->daddr)) + fl4->saddr = inet_select_addr(dev_out, 0, + fl4->flowi4_scope); +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index 55d96c392e7f..99eb909c9d5f 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -1468,7 +1468,10 @@ static int tcp_shifted_skb(struct sock *sk, struct sk_buff *skb, + tp->lost_cnt_hint -= tcp_skb_pcount(prev); + } + +- TCP_SKB_CB(skb)->tcp_flags |= TCP_SKB_CB(prev)->tcp_flags; ++ TCP_SKB_CB(prev)->tcp_flags |= TCP_SKB_CB(skb)->tcp_flags; ++ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) ++ TCP_SKB_CB(prev)->end_seq++; ++ + if (skb == tcp_highest_sack(sk)) + tcp_advance_highest_sack(sk, skb); + +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c +index 12999a3aaf95..987f5cc706b4 100644 +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -933,6 +933,9 @@ static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb) + static void tcp_set_skb_tso_segs(const struct sock *sk, struct sk_buff *skb, + unsigned int mss_now) + { ++ /* Make sure we own this skb before messing gso_size/gso_segs */ ++ WARN_ON_ONCE(skb_cloned(skb)); ++ + if (skb->len <= mss_now || !sk_can_gso(sk) || + skb->ip_summed == CHECKSUM_NONE) { + /* Avoid the costly divide in the normal +@@ -1014,9 +1017,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, + if (nsize < 0) + nsize = 0; + +- if (skb_cloned(skb) && +- skb_is_nonlinear(skb) && +- pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) ++ if (skb_unclone(skb, GFP_ATOMIC)) + return -ENOMEM; + + /* Get a new skb... force flag on. */ +@@ -2129,6 +2130,8 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) + int oldpcount = tcp_skb_pcount(skb); + + if (unlikely(oldpcount > 1)) { ++ if (skb_unclone(skb, GFP_ATOMIC)) ++ return -ENOMEM; + tcp_init_tso_segs(sk, skb, cur_mss); + tcp_adjust_pcount(sk, skb, oldpcount - tcp_skb_pcount(skb)); + } +diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c +index 73f1a00a96af..e38290b7c7a1 100644 +--- a/net/ipv6/inet6_hashtables.c ++++ b/net/ipv6/inet6_hashtables.c +@@ -110,7 +110,7 @@ begintw: + goto out; + } + if (!INET6_TW_MATCH(sk, net, hash, saddr, daddr, ports, dif)) { +- sock_put(sk); ++ inet_twsk_put(inet_twsk(sk)); + goto begintw; + } + goto out; +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index 1acfb19cb570..7dabea3a7125 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -1345,7 +1345,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, + skb = skb_peek_tail(&sk->sk_write_queue); + cork->length += length; + if (((length > mtu) || +- (skb && skb_is_gso(skb))) && ++ (skb && skb_has_frags(skb))) && + (sk->sk_protocol == IPPROTO_UDP) && + (rt->dst.dev->features & NETIF_F_UFO)) { + err = ip6_ufo_append_data(sk, getfrag, from, length, +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 016ed7c22fc9..4f768a4c2907 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -818,7 +818,7 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, + } + + static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, int oif, +- struct flowi6 *fl6, int flags) ++ struct flowi6 *fl6, int flags, bool input) + { + struct fib6_node *fn; + struct rt6_info *rt, *nrt; +@@ -826,8 +826,11 @@ static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, + int attempts = 3; + int err; + int reachable = net->ipv6.devconf_all->forwarding ? 0 : RT6_LOOKUP_F_REACHABLE; ++ int local = RTF_NONEXTHOP; + + strict |= flags & RT6_LOOKUP_F_IFACE; ++ if (input) ++ local |= RTF_LOCAL; + + relookup: + read_lock_bh(&table->tb6_lock); +@@ -847,7 +850,7 @@ restart: + read_unlock_bh(&table->tb6_lock); + + if (!dst_get_neighbour_noref_raw(&rt->dst) && +- !(rt->rt6i_flags & (RTF_NONEXTHOP | RTF_LOCAL))) ++ !(rt->rt6i_flags & local)) + nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr); + else if (!(rt->dst.flags & DST_HOST)) + nrt = rt6_alloc_clone(rt, &fl6->daddr); +@@ -891,7 +894,7 @@ out2: + static struct rt6_info *ip6_pol_route_input(struct net *net, struct fib6_table *table, + struct flowi6 *fl6, int flags) + { +- return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, flags); ++ return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, flags, true); + } + + static struct dst_entry *ip6_route_input_lookup(struct net *net, +@@ -924,7 +927,7 @@ void ip6_route_input(struct sk_buff *skb) + static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table, + struct flowi6 *fl6, int flags) + { +- return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags); ++ return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags, false); + } + + struct dst_entry * ip6_route_output(struct net *net, const struct sock *sk, +diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c +index b2982f4214d1..904bc098790d 100644 +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -357,7 +357,9 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh + goto error_put_sess_tun; + } + ++ local_bh_disable(); + l2tp_xmit_skb(session, skb, session->hdr_len); ++ local_bh_enable(); + + sock_put(ps->tunnel_sock); + sock_put(sk); +@@ -432,7 +434,9 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) + skb->data[0] = ppph[0]; + skb->data[1] = ppph[1]; + ++ local_bh_disable(); + l2tp_xmit_skb(session, skb, session->hdr_len); ++ local_bh_enable(); + + sock_put(sk_tun); + sock_put(sk); +diff --git a/net/sctp/output.c b/net/sctp/output.c +index 32ba8d0e50e2..cf3e22c586a6 100644 +--- a/net/sctp/output.c ++++ b/net/sctp/output.c +@@ -518,7 +518,8 @@ int sctp_packet_transmit(struct sctp_packet *packet) + * by CRC32-C as described in . + */ + if (!sctp_checksum_disable) { +- if (!(dst->dev->features & NETIF_F_SCTP_CSUM)) { ++ if (!(dst->dev->features & NETIF_F_SCTP_CSUM) || ++ (dst_xfrm(dst) != NULL) || packet->ipfragok) { + __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len); + + /* 3) Put the resultant value into the checksum field in the +diff --git a/net/socket.c b/net/socket.c +index 47ce3ea44300..acc769562707 100644 +--- a/net/socket.c ++++ b/net/socket.c +@@ -1899,6 +1899,16 @@ struct used_address { + unsigned int name_len; + }; + ++static int copy_msghdr_from_user(struct msghdr *kmsg, ++ struct msghdr __user *umsg) ++{ ++ if (copy_from_user(kmsg, umsg, sizeof(struct msghdr))) ++ return -EFAULT; ++ if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) ++ return -EINVAL; ++ return 0; ++} ++ + static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg, + struct msghdr *msg_sys, unsigned flags, + struct used_address *used_address) +@@ -1917,8 +1927,11 @@ static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg, + if (MSG_CMSG_COMPAT & flags) { + if (get_compat_msghdr(msg_sys, msg_compat)) + return -EFAULT; +- } else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr))) +- return -EFAULT; ++ } else { ++ err = copy_msghdr_from_user(msg_sys, msg); ++ if (err) ++ return err; ++ } + + /* do not move before msg_sys is valid */ + err = -EMSGSIZE; +@@ -2129,8 +2142,11 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, + if (MSG_CMSG_COMPAT & flags) { + if (get_compat_msghdr(msg_sys, msg_compat)) + return -EFAULT; +- } else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr))) +- return -EFAULT; ++ } else { ++ err = copy_msghdr_from_user(msg_sys, msg); ++ if (err) ++ return err; ++ } + + err = -EMSGSIZE; + if (msg_sys->msg_iovlen > UIO_MAXIOV) +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index c4821fd23b79..ed005b425a7c 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -1247,6 +1247,15 @@ static int unix_socketpair(struct socket *socka, struct socket *sockb) + return 0; + } + ++static void unix_sock_inherit_flags(const struct socket *old, ++ struct socket *new) ++{ ++ if (test_bit(SOCK_PASSCRED, &old->flags)) ++ set_bit(SOCK_PASSCRED, &new->flags); ++ if (test_bit(SOCK_PASSSEC, &old->flags)) ++ set_bit(SOCK_PASSSEC, &new->flags); ++} ++ + static int unix_accept(struct socket *sock, struct socket *newsock, int flags) + { + struct sock *sk = sock->sk; +@@ -1281,6 +1290,7 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags) + /* attach accepted sock to socket */ + unix_state_lock(tsk); + newsock->state = SS_CONNECTED; ++ unix_sock_inherit_flags(sock, newsock); + sock_graft(tsk, newsock); + unix_state_unlock(tsk); + return 0; +diff --git a/net/unix/diag.c b/net/unix/diag.c +index f0486ae9ebe6..2656840cf203 100644 +--- a/net/unix/diag.c ++++ b/net/unix/diag.c +@@ -134,6 +134,7 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_r + rep->udiag_family = AF_UNIX; + rep->udiag_type = sk->sk_type; + rep->udiag_state = sk->sk_state; ++ rep->pad = 0; + rep->udiag_ino = sk_ino; + sock_diag_save_cookie(sk, rep->udiag_cookie); + +diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c +index c4ad7958af52..617a310025b1 100644 +--- a/net/wireless/radiotap.c ++++ b/net/wireless/radiotap.c +@@ -95,6 +95,10 @@ int ieee80211_radiotap_iterator_init( + struct ieee80211_radiotap_header *radiotap_header, + int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns) + { ++ /* check the radiotap header can actually be present */ ++ if (max_length < sizeof(struct ieee80211_radiotap_header)) ++ return -EINVAL; ++ + /* Linux only supports version 0 radiotap format */ + if (radiotap_header->it_version) + return -EINVAL; +@@ -129,7 +133,8 @@ int ieee80211_radiotap_iterator_init( + */ + + if ((unsigned long)iterator->_arg - +- (unsigned long)iterator->_rtheader > ++ (unsigned long)iterator->_rtheader + ++ sizeof(uint32_t) > + (unsigned long)iterator->_max_length) + return -EINVAL; + } diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.68-69.patch b/patch/kernel/sun8i-default/0001-patch-3.4.68-69.patch new file mode 100644 index 000000000..ddc91704b --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.68-69.patch @@ -0,0 +1,841 @@ +diff --git a/Makefile b/Makefile +index 656c45f09128..2f9a0467ede5 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 68 ++SUBLEVEL = 69 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S +index 37aabd772fbb..d2d58258aea6 100644 +--- a/arch/parisc/kernel/head.S ++++ b/arch/parisc/kernel/head.S +@@ -195,6 +195,8 @@ common_stext: + ldw MEM_PDC_HI(%r0),%r6 + depd %r6, 31, 32, %r3 /* move to upper word */ + ++ mfctl %cr30,%r6 /* PCX-W2 firmware bug */ ++ + ldo PDC_PSW(%r0),%arg0 /* 21 */ + ldo PDC_PSW_SET_DEFAULTS(%r0),%arg1 /* 2 */ + ldo PDC_PSW_WIDE_BIT(%r0),%arg2 /* 2 */ +@@ -203,6 +205,8 @@ common_stext: + copy %r0,%arg3 + + stext_pdc_ret: ++ mtctl %r6,%cr30 /* restore task thread info */ ++ + /* restore rfi target address*/ + ldd TI_TASK-THREAD_SZ_ALGN(%sp), %r10 + tophys_r1 %r10 +diff --git a/arch/um/kernel/exitcode.c b/arch/um/kernel/exitcode.c +index 829df49dee99..41ebbfebb333 100644 +--- a/arch/um/kernel/exitcode.c ++++ b/arch/um/kernel/exitcode.c +@@ -40,9 +40,11 @@ static ssize_t exitcode_proc_write(struct file *file, + const char __user *buffer, size_t count, loff_t *pos) + { + char *end, buf[sizeof("nnnnn\0")]; ++ size_t size; + int tmp; + +- if (copy_from_user(buf, buffer, count)) ++ size = min(count, sizeof(buf)); ++ if (copy_from_user(buf, buffer, size)) + return -EFAULT; + + tmp = simple_strtol(buf, &end, 0); +diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c +index d78869a00b11..b08caaa59813 100644 +--- a/arch/xtensa/kernel/signal.c ++++ b/arch/xtensa/kernel/signal.c +@@ -343,7 +343,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info, + + sp = regs->areg[1]; + +- if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp)) { ++ if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && sas_ss_flags(sp) == 0) { + sp = current->sas_ss_sp + current->sas_ss_size; + } + +diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c +index e47c224d7c28..37fb4d6069a2 100644 +--- a/drivers/ata/libata-eh.c ++++ b/drivers/ata/libata-eh.c +@@ -1287,14 +1287,14 @@ void ata_eh_qc_complete(struct ata_queued_cmd *qc) + * should be retried. To be used from EH. + * + * SCSI midlayer limits the number of retries to scmd->allowed. +- * scmd->retries is decremented for commands which get retried ++ * scmd->allowed is incremented for commands which get retried + * due to unrelated failures (qc->err_mask is zero). + */ + void ata_eh_qc_retry(struct ata_queued_cmd *qc) + { + struct scsi_cmnd *scmd = qc->scsicmd; +- if (!qc->err_mask && scmd->retries) +- scmd->retries--; ++ if (!qc->err_mask) ++ scmd->allowed++; + __ata_eh_qc_complete(qc); + } + +diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c +index 6116e3b75393..e9f1ef5d9340 100644 +--- a/drivers/gpu/drm/drm_drv.c ++++ b/drivers/gpu/drm/drm_drv.c +@@ -420,9 +420,16 @@ long drm_ioctl(struct file *filp, + asize = drv_size; + } + else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) { ++ u32 drv_size; ++ + ioctl = &drm_ioctls[nr]; +- cmd = ioctl->cmd; ++ ++ drv_size = _IOC_SIZE(ioctl->cmd); + usize = asize = _IOC_SIZE(cmd); ++ if (drv_size > asize) ++ asize = drv_size; ++ ++ cmd = ioctl->cmd; + } else + goto err_i1; + +diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c +index 2f755e2aeb86..6f4627fe24a1 100644 +--- a/drivers/gpu/drm/radeon/atombios_encoders.c ++++ b/drivers/gpu/drm/radeon/atombios_encoders.c +@@ -1430,7 +1430,7 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) + * does the same thing and more. + */ + if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730) && +- (rdev->family != CHIP_RS880)) ++ (rdev->family != CHIP_RS780) && (rdev->family != CHIP_RS880)) + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); + } + if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { +diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c +index ce5f0449e1b6..75e66c612505 100644 +--- a/drivers/md/raid1.c ++++ b/drivers/md/raid1.c +@@ -1357,6 +1357,7 @@ static int raid1_spare_active(struct mddev *mddev) + } + } + if (rdev ++ && rdev->recovery_offset == MaxSector + && !test_bit(Faulty, &rdev->flags) + && !test_and_set_bit(In_sync, &rdev->flags)) { + count++; +diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c +index f7febd8e3720..99a102d186ce 100644 +--- a/drivers/md/raid10.c ++++ b/drivers/md/raid10.c +@@ -1534,6 +1534,7 @@ static int raid10_spare_active(struct mddev *mddev) + } + sysfs_notify_dirent_safe(tmp->replacement->sysfs_state); + } else if (tmp->rdev ++ && tmp->rdev->recovery_offset == MaxSector + && !test_bit(Faulty, &tmp->rdev->flags) + && !test_and_set_bit(In_sync, &tmp->rdev->flags)) { + count++; +diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c +index 00baa7e094f4..e2131ca64a5f 100644 +--- a/drivers/net/can/flexcan.c ++++ b/drivers/net/can/flexcan.c +@@ -60,7 +60,7 @@ + #define FLEXCAN_MCR_BCC BIT(16) + #define FLEXCAN_MCR_LPRIO_EN BIT(13) + #define FLEXCAN_MCR_AEN BIT(12) +-#define FLEXCAN_MCR_MAXMB(x) ((x) & 0xf) ++#define FLEXCAN_MCR_MAXMB(x) ((x) & 0x1f) + #define FLEXCAN_MCR_IDAM_A (0 << 8) + #define FLEXCAN_MCR_IDAM_B (1 << 8) + #define FLEXCAN_MCR_IDAM_C (2 << 8) +@@ -701,9 +701,11 @@ static int flexcan_chip_start(struct net_device *dev) + * + */ + reg_mcr = flexcan_read(®s->mcr); ++ reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff); + reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT | + FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | +- FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_SRX_DIS; ++ FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_SRX_DIS | ++ FLEXCAN_MCR_MAXMB(FLEXCAN_TX_BUF_ID); + netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr); + flexcan_write(reg_mcr, ®s->mcr); + +@@ -744,6 +746,10 @@ static int flexcan_chip_start(struct net_device *dev) + ®s->cantxfg[i].can_ctrl); + } + ++ /* Abort any pending TX, mark Mailbox as INACTIVE */ ++ flexcan_write(FLEXCAN_MB_CNT_CODE(0x4), ++ ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl); ++ + /* acceptance mask/acceptance code (accept everything) */ + flexcan_write(0x0, ®s->rxgmask); + flexcan_write(0x0, ®s->rx14mask); +diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +index 21bc827c5fa6..9adb21a1133e 100644 +--- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c ++++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +@@ -343,7 +343,8 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw, + (bool)GET_RX_DESC_PAGGR(pdesc)); + rx_status->mactime = GET_RX_DESC_TSFL(pdesc); + if (phystatus) { +- p_drvinfo = (struct rx_fwinfo_92c *)(pdesc + RTL_RX_DESC_SIZE); ++ p_drvinfo = (struct rx_fwinfo_92c *)(skb->data + ++ stats->rx_bufshift); + rtl92c_translate_rx_signal_stuff(hw, skb, stats, pdesc, + p_drvinfo); + } +diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c +index 0d279c445a30..e9313f85bc70 100644 +--- a/drivers/scsi/aacraid/linit.c ++++ b/drivers/scsi/aacraid/linit.c +@@ -777,6 +777,8 @@ static long aac_compat_do_ioctl(struct aac_dev *dev, unsigned cmd, unsigned long + static int aac_compat_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) + { + struct aac_dev *dev = (struct aac_dev *)sdev->host->hostdata; ++ if (!capable(CAP_SYS_RAWIO)) ++ return -EPERM; + return aac_compat_do_ioctl(dev, cmd, (unsigned long)arg); + } + +diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c +index cf3059216958..c0d612ff8519 100644 +--- a/drivers/staging/bcm/Bcmchar.c ++++ b/drivers/staging/bcm/Bcmchar.c +@@ -1957,6 +1957,7 @@ cntrlEnd: + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Called IOCTL_BCM_GET_DEVICE_DRIVER_INFO\n"); + ++ memset(&DevInfo, 0, sizeof(DevInfo)); + DevInfo.MaxRDMBufferSize = BUFFER_4K; + DevInfo.u32DSDStartOffset = EEPROM_CALPARAM_START; + DevInfo.u32RxAlignmentCorrection = 0; +diff --git a/drivers/staging/ozwpan/ozcdev.c b/drivers/staging/ozwpan/ozcdev.c +index 1c380d687963..1c9245119567 100644 +--- a/drivers/staging/ozwpan/ozcdev.c ++++ b/drivers/staging/ozwpan/ozcdev.c +@@ -153,6 +153,9 @@ ssize_t oz_cdev_write(struct file *filp, const char __user *buf, size_t count, + struct oz_app_hdr *app_hdr; + struct oz_serial_ctx *ctx; + ++ if (count > sizeof(ei->data) - sizeof(*elt) - sizeof(*app_hdr)) ++ return -EINVAL; ++ + spin_lock_bh(&g_cdev.lock); + pd = g_cdev.active_pd; + if (pd) +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index 8659cd94639a..f6904d819ca8 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -119,6 +119,9 @@ static const struct usb_device_id usb_quirk_list[] = { + /* Alcor Micro Corp. Hub */ + { USB_DEVICE(0x058f, 0x9254), .driver_info = USB_QUIRK_RESET_RESUME }, + ++ /* MicroTouch Systems touchscreen */ ++ { USB_DEVICE(0x0596, 0x051e), .driver_info = USB_QUIRK_RESET_RESUME }, ++ + /* appletouch */ + { USB_DEVICE(0x05ac, 0x021a), .driver_info = USB_QUIRK_RESET_RESUME }, + +@@ -152,6 +155,9 @@ static const struct usb_device_id usb_quirk_list[] = { + /* Broadcom BCM92035DGROM BT dongle */ + { USB_DEVICE(0x0a5c, 0x2021), .driver_info = USB_QUIRK_RESET_RESUME }, + ++ /* MAYA44USB sound device */ ++ { USB_DEVICE(0x0a92, 0x0091), .driver_info = USB_QUIRK_RESET_RESUME }, ++ + /* Action Semiconductor flash disk */ + { USB_DEVICE(0x10d6, 0x2200), .driver_info = + USB_QUIRK_STRING_FETCH_255 }, +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index 3e4c27dd1590..904e8341b2c9 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -916,6 +916,7 @@ static struct usb_device_id id_table_combined [] = { + { USB_DEVICE(FTDI_VID, FTDI_LUMEL_PD12_PID) }, + /* Crucible Devices */ + { USB_DEVICE(FTDI_VID, FTDI_CT_COMET_PID) }, ++ { USB_DEVICE(FTDI_VID, FTDI_Z3X_PID) }, + { }, /* Optional parameter entry */ + { } /* Terminating entry */ + }; +diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h +index 1b8af461b522..a7019d1e3058 100644 +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -1307,3 +1307,9 @@ + * Manufacturer: Crucible Technologies + */ + #define FTDI_CT_COMET_PID 0x8e08 ++ ++/* ++ * Product: Z3X Box ++ * Manufacturer: Smart GSM Team ++ */ ++#define FTDI_Z3X_PID 0x0011 +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index b3440c66a995..57277bccb9ef 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -707,6 +707,222 @@ static const struct usb_device_id option_ids[] = { + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7A) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7B) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x01) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x02) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x03) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x04) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x05) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x06) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x0A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x0B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x0D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x0E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x0F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x10) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x12) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x13) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x14) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x15) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x17) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x18) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x19) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x1A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x1B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x1C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x31) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x32) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x33) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x34) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x35) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x36) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x3A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x3B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x3D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x3E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x3F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x48) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x49) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x4A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x4B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x4C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x61) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x62) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x63) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x64) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x65) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x66) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x6A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x6B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x6D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x6E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x6F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x78) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x79) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x7A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x7B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x7C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x01) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x02) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x03) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x04) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x05) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x06) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x0A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x0B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x0D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x0E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x0F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x10) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x12) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x13) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x14) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x15) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x17) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x18) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x19) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x1A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x1B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x1C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x31) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x32) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x33) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x34) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x35) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x36) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x3A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x3B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x3D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x3E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x3F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x48) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x49) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x4A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x4B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x4C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x61) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x62) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x63) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x64) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x65) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x66) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x6A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x6B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x6D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x6E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x6F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x78) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x79) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x7A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x7B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x7C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x01) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x02) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x03) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x04) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x05) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x06) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x0A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x0B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x0D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x0E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x0F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x10) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x12) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x13) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x14) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x15) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x17) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x18) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x19) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x1A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x1B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x1C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x31) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x32) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x33) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x34) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x35) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x36) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x3A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x3B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x3D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x3E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x3F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x48) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x49) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x4A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x4B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x4C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x61) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x62) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x63) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x64) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x65) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x66) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x6A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x6B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x6D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x6E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x6F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x78) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x79) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x7A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x7B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x7C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x01) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x02) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x03) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x04) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x05) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x06) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x0A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x0B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x0D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x0E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x0F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x10) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x12) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x13) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x14) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x15) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x17) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x18) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x19) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x1A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x1B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x1C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x31) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x32) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x33) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x34) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x35) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x36) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x3A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x3B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x3D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x3E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x3F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x48) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x49) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x4A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x4B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x4C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x61) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x62) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x63) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x64) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x65) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x66) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x6A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x6B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x6D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x6E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x6F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x78) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x79) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x7A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x7B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x7C) }, + + + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, +diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c +index c1a3e603279c..7f464c513ba0 100644 +--- a/fs/jfs/jfs_inode.c ++++ b/fs/jfs/jfs_inode.c +@@ -95,7 +95,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode) + + if (insert_inode_locked(inode) < 0) { + rc = -EINVAL; +- goto fail_unlock; ++ goto fail_put; + } + + inode_init_owner(inode, parent, mode); +@@ -156,7 +156,6 @@ struct inode *ialloc(struct inode *parent, umode_t mode) + fail_drop: + dquot_drop(inode); + inode->i_flags |= S_NOQUOTA; +-fail_unlock: + clear_nlink(inode); + unlock_new_inode(inode); + fail_put: +diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c +index 9cd928f7a7c6..0d37a6fd18af 100644 +--- a/kernel/time/clockevents.c ++++ b/kernel/time/clockevents.c +@@ -30,29 +30,64 @@ static RAW_NOTIFIER_HEAD(clockevents_chain); + /* Protection for the above */ + static DEFINE_RAW_SPINLOCK(clockevents_lock); + +-/** +- * clockevents_delta2ns - Convert a latch value (device ticks) to nanoseconds +- * @latch: value to convert +- * @evt: pointer to clock event device descriptor +- * +- * Math helper, returns latch value converted to nanoseconds (bound checked) +- */ +-u64 clockevent_delta2ns(unsigned long latch, struct clock_event_device *evt) ++static u64 cev_delta2ns(unsigned long latch, struct clock_event_device *evt, ++ bool ismax) + { + u64 clc = (u64) latch << evt->shift; ++ u64 rnd; + + if (unlikely(!evt->mult)) { + evt->mult = 1; + WARN_ON(1); + } ++ rnd = (u64) evt->mult - 1; ++ ++ /* ++ * Upper bound sanity check. If the backwards conversion is ++ * not equal latch, we know that the above shift overflowed. ++ */ ++ if ((clc >> evt->shift) != (u64)latch) ++ clc = ~0ULL; ++ ++ /* ++ * Scaled math oddities: ++ * ++ * For mult <= (1 << shift) we can safely add mult - 1 to ++ * prevent integer rounding loss. So the backwards conversion ++ * from nsec to device ticks will be correct. ++ * ++ * For mult > (1 << shift), i.e. device frequency is > 1GHz we ++ * need to be careful. Adding mult - 1 will result in a value ++ * which when converted back to device ticks can be larger ++ * than latch by up to (mult - 1) >> shift. For the min_delta ++ * calculation we still want to apply this in order to stay ++ * above the minimum device ticks limit. For the upper limit ++ * we would end up with a latch value larger than the upper ++ * limit of the device, so we omit the add to stay below the ++ * device upper boundary. ++ * ++ * Also omit the add if it would overflow the u64 boundary. ++ */ ++ if ((~0ULL - clc > rnd) && ++ (!ismax || evt->mult <= (1U << evt->shift))) ++ clc += rnd; + + do_div(clc, evt->mult); +- if (clc < 1000) +- clc = 1000; +- if (clc > KTIME_MAX) +- clc = KTIME_MAX; + +- return clc; ++ /* Deltas less than 1usec are pointless noise */ ++ return clc > 1000 ? clc : 1000; ++} ++ ++/** ++ * clockevents_delta2ns - Convert a latch value (device ticks) to nanoseconds ++ * @latch: value to convert ++ * @evt: pointer to clock event device descriptor ++ * ++ * Math helper, returns latch value converted to nanoseconds (bound checked) ++ */ ++u64 clockevent_delta2ns(unsigned long latch, struct clock_event_device *evt) ++{ ++ return cev_delta2ns(latch, evt, false); + } + EXPORT_SYMBOL_GPL(clockevent_delta2ns); + +@@ -318,8 +353,8 @@ static void clockevents_config(struct clock_event_device *dev, + sec = 600; + + clockevents_calc_mult_shift(dev, freq, sec); +- dev->min_delta_ns = clockevent_delta2ns(dev->min_delta_ticks, dev); +- dev->max_delta_ns = clockevent_delta2ns(dev->max_delta_ticks, dev); ++ dev->min_delta_ns = cev_delta2ns(dev->min_delta_ticks, dev, false); ++ dev->max_delta_ns = cev_delta2ns(dev->max_delta_ticks, dev, true); + } + + /** +diff --git a/lib/scatterlist.c b/lib/scatterlist.c +index 6096e89bee55..8c2f278e5eb7 100644 +--- a/lib/scatterlist.c ++++ b/lib/scatterlist.c +@@ -419,7 +419,8 @@ void sg_miter_stop(struct sg_mapping_iter *miter) + if (miter->addr) { + miter->__offset += miter->consumed; + +- if (miter->__flags & SG_MITER_TO_SG) ++ if ((miter->__flags & SG_MITER_TO_SG) && ++ !PageSlab(miter->page)) + flush_kernel_dcache_page(miter->page); + + if (miter->__flags & SG_MITER_ATOMIC) { +diff --git a/mm/swap.c b/mm/swap.c +index 5c13f1338972..f689e9a03204 100644 +--- a/mm/swap.c ++++ b/mm/swap.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + #include "internal.h" + +@@ -68,13 +69,26 @@ static void __put_compound_page(struct page *page) + { + compound_page_dtor *dtor; + +- __page_cache_release(page); ++ if (!PageHuge(page)) ++ __page_cache_release(page); + dtor = get_compound_page_dtor(page); + (*dtor)(page); + } + + static void put_compound_page(struct page *page) + { ++ /* ++ * hugetlbfs pages cannot be split from under us. If this is a ++ * hugetlbfs page, check refcount on head page and release the page if ++ * the refcount becomes zero. ++ */ ++ if (PageHuge(page)) { ++ page = compound_head(page); ++ if (put_page_testzero(page)) ++ __put_compound_page(page); ++ return; ++ } ++ + if (unlikely(PageTail(page))) { + /* __split_huge_page_refcount can run under us */ + struct page *page_head = compound_trans_head(page); +@@ -159,8 +173,20 @@ bool __get_page_tail(struct page *page) + */ + unsigned long flags; + bool got = false; +- struct page *page_head = compound_trans_head(page); ++ struct page *page_head; ++ ++ /* ++ * If this is a hugetlbfs page it cannot be split under us. Simply ++ * increment refcount for the head page. ++ */ ++ if (PageHuge(page)) { ++ page_head = compound_head(page); ++ atomic_inc(&page_head->_count); ++ got = true; ++ goto out; ++ } + ++ page_head = compound_trans_head(page); + if (likely(page != page_head && get_page_unless_zero(page_head))) { + /* + * page_head wasn't a dangling pointer but it +@@ -178,6 +204,7 @@ bool __get_page_tail(struct page *page) + if (unlikely(!got)) + put_page(page_head); + } ++out: + return got; + } + EXPORT_SYMBOL(__get_page_tail); +diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h +index 05160dbeaf44..226be1364ef3 100644 +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -789,12 +789,15 @@ struct tpt_led_trigger { + * that the scan completed. + * @SCAN_ABORTED: Set for our scan work function when the driver reported + * a scan complete for an aborted scan. ++ * @SCAN_HW_CANCELLED: Set for our scan work function when the scan is being ++ * cancelled. + */ + enum { + SCAN_SW_SCANNING, + SCAN_HW_SCANNING, + SCAN_COMPLETED, + SCAN_ABORTED, ++ SCAN_HW_CANCELLED, + }; + + /** +diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c +index bcc57f93adc4..9520749bd1e3 100644 +--- a/net/mac80211/scan.c ++++ b/net/mac80211/scan.c +@@ -259,6 +259,9 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) + enum ieee80211_band band; + int i, ielen, n_chans; + ++ if (test_bit(SCAN_HW_CANCELLED, &local->scanning)) ++ return false; ++ + do { + if (local->hw_scan_band == IEEE80211_NUM_BANDS) + return false; +@@ -844,7 +847,23 @@ void ieee80211_scan_cancel(struct ieee80211_local *local) + if (!local->scan_req) + goto out; + ++ /* ++ * We have a scan running and the driver already reported completion, ++ * but the worker hasn't run yet or is stuck on the mutex - mark it as ++ * cancelled. ++ */ ++ if (test_bit(SCAN_HW_SCANNING, &local->scanning) && ++ test_bit(SCAN_COMPLETED, &local->scanning)) { ++ set_bit(SCAN_HW_CANCELLED, &local->scanning); ++ goto out; ++ } ++ + if (test_bit(SCAN_HW_SCANNING, &local->scanning)) { ++ /* ++ * Make sure that __ieee80211_scan_completed doesn't trigger a ++ * scan on another band. ++ */ ++ set_bit(SCAN_HW_CANCELLED, &local->scanning); + if (local->ops->cancel_hw_scan) + drv_cancel_hw_scan(local, local->scan_sdata); + goto out; +diff --git a/net/mac80211/status.c b/net/mac80211/status.c +index 47b117f3f567..b992a49fbe08 100644 +--- a/net/mac80211/status.c ++++ b/net/mac80211/status.c +@@ -183,6 +183,9 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb) + struct ieee80211_local *local = sta->local; + struct ieee80211_sub_if_data *sdata = sta->sdata; + ++ if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) ++ sta->last_rx = jiffies; ++ + if (ieee80211_is_data_qos(mgmt->frame_control)) { + struct ieee80211_hdr *hdr = (void *) skb->data; + u8 *qc = ieee80211_get_qos_ctl(hdr); +diff --git a/sound/core/pcm.c b/sound/core/pcm.c +index e30e1be30a21..6355540fdb0d 100644 +--- a/sound/core/pcm.c ++++ b/sound/core/pcm.c +@@ -49,6 +49,8 @@ static struct snd_pcm *snd_pcm_get(struct snd_card *card, int device) + struct snd_pcm *pcm; + + list_for_each_entry(pcm, &snd_pcm_devices, list) { ++ if (pcm->internal) ++ continue; + if (pcm->card == card && pcm->device == device) + return pcm; + } +@@ -60,6 +62,8 @@ static int snd_pcm_next(struct snd_card *card, int device) + struct snd_pcm *pcm; + + list_for_each_entry(pcm, &snd_pcm_devices, list) { ++ if (pcm->internal) ++ continue; + if (pcm->card == card && pcm->device > device) + return pcm->device; + else if (pcm->card->number > card->number) +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 33abb782a54b..810f1fc2c3f4 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -6833,6 +6833,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { + SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), + SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), + SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_ASUS_MODE4), ++ SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_ASUS_MODE4), + SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), + SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), + SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), +diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c +index 6c028c470601..fec98cf3b2c0 100644 +--- a/sound/soc/codecs/wm_hubs.c ++++ b/sound/soc/codecs/wm_hubs.c +@@ -413,6 +413,7 @@ static int hp_supply_event(struct snd_soc_dapm_widget *w, + hubs->hp_startup_mode); + break; + } ++ break; + + case SND_SOC_DAPM_PRE_PMD: + snd_soc_update_bits(codec, WM8993_CHARGE_PUMP_1, +diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c +index 9ae82a4eb71e..e39364b6b080 100644 +--- a/sound/soc/soc-dapm.c ++++ b/sound/soc/soc-dapm.c +@@ -1590,7 +1590,7 @@ static ssize_t dapm_widget_power_read_file(struct file *file, + w->active ? "active" : "inactive"); + + list_for_each_entry(p, &w->sources, list_sink) { +- if (p->connected && !p->connected(w, p->sink)) ++ if (p->connected && !p->connected(w, p->source)) + continue; + + if (p->connect) diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.69-70.patch b/patch/kernel/sun8i-default/0001-patch-3.4.69-70.patch new file mode 100644 index 000000000..d841423df --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.69-70.patch @@ -0,0 +1,424 @@ +diff --git a/Makefile b/Makefile +index 2f9a0467..d7c0a383 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 69 ++SUBLEVEL = 70 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S +index 650d5923..94b0650e 100644 +--- a/arch/arm/lib/memset.S ++++ b/arch/arm/lib/memset.S +@@ -14,27 +14,15 @@ + + .text + .align 5 +- .word 0 +- +-1: subs r2, r2, #4 @ 1 do we have enough +- blt 5f @ 1 bytes to align with? +- cmp r3, #2 @ 1 +- strltb r1, [r0], #1 @ 1 +- strleb r1, [r0], #1 @ 1 +- strb r1, [r0], #1 @ 1 +- add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3)) +-/* +- * The pointer is now aligned and the length is adjusted. Try doing the +- * memset again. +- */ + + ENTRY(memset) + ands r3, r0, #3 @ 1 unaligned? +- bne 1b @ 1 ++ mov ip, r0 @ preserve r0 as return value ++ bne 6f @ 1 + /* +- * we know that the pointer in r0 is aligned to a word boundary. ++ * we know that the pointer in ip is aligned to a word boundary. + */ +- orr r1, r1, r1, lsl #8 ++1: orr r1, r1, r1, lsl #8 + orr r1, r1, r1, lsl #16 + mov r3, r1 + cmp r2, #16 +@@ -43,29 +31,28 @@ ENTRY(memset) + #if ! CALGN(1)+0 + + /* +- * We need an extra register for this loop - save the return address and +- * use the LR ++ * We need 2 extra registers for this loop - use r8 and the LR + */ +- str lr, [sp, #-4]! +- mov ip, r1 ++ stmfd sp!, {r8, lr} ++ mov r8, r1 + mov lr, r1 + + 2: subs r2, r2, #64 +- stmgeia r0!, {r1, r3, ip, lr} @ 64 bytes at a time. +- stmgeia r0!, {r1, r3, ip, lr} +- stmgeia r0!, {r1, r3, ip, lr} +- stmgeia r0!, {r1, r3, ip, lr} ++ stmgeia ip!, {r1, r3, r8, lr} @ 64 bytes at a time. ++ stmgeia ip!, {r1, r3, r8, lr} ++ stmgeia ip!, {r1, r3, r8, lr} ++ stmgeia ip!, {r1, r3, r8, lr} + bgt 2b +- ldmeqfd sp!, {pc} @ Now <64 bytes to go. ++ ldmeqfd sp!, {r8, pc} @ Now <64 bytes to go. + /* + * No need to correct the count; we're only testing bits from now on + */ + tst r2, #32 +- stmneia r0!, {r1, r3, ip, lr} +- stmneia r0!, {r1, r3, ip, lr} ++ stmneia ip!, {r1, r3, r8, lr} ++ stmneia ip!, {r1, r3, r8, lr} + tst r2, #16 +- stmneia r0!, {r1, r3, ip, lr} +- ldr lr, [sp], #4 ++ stmneia ip!, {r1, r3, r8, lr} ++ ldmfd sp!, {r8, lr} + + #else + +@@ -74,54 +61,63 @@ ENTRY(memset) + * whole cache lines at once. + */ + +- stmfd sp!, {r4-r7, lr} ++ stmfd sp!, {r4-r8, lr} + mov r4, r1 + mov r5, r1 + mov r6, r1 + mov r7, r1 +- mov ip, r1 ++ mov r8, r1 + mov lr, r1 + + cmp r2, #96 +- tstgt r0, #31 ++ tstgt ip, #31 + ble 3f + +- and ip, r0, #31 +- rsb ip, ip, #32 +- sub r2, r2, ip +- movs ip, ip, lsl #(32 - 4) +- stmcsia r0!, {r4, r5, r6, r7} +- stmmiia r0!, {r4, r5} +- tst ip, #(1 << 30) +- mov ip, r1 +- strne r1, [r0], #4 ++ and r8, ip, #31 ++ rsb r8, r8, #32 ++ sub r2, r2, r8 ++ movs r8, r8, lsl #(32 - 4) ++ stmcsia ip!, {r4, r5, r6, r7} ++ stmmiia ip!, {r4, r5} ++ tst r8, #(1 << 30) ++ mov r8, r1 ++ strne r1, [ip], #4 + + 3: subs r2, r2, #64 +- stmgeia r0!, {r1, r3-r7, ip, lr} +- stmgeia r0!, {r1, r3-r7, ip, lr} ++ stmgeia ip!, {r1, r3-r8, lr} ++ stmgeia ip!, {r1, r3-r8, lr} + bgt 3b +- ldmeqfd sp!, {r4-r7, pc} ++ ldmeqfd sp!, {r4-r8, pc} + + tst r2, #32 +- stmneia r0!, {r1, r3-r7, ip, lr} ++ stmneia ip!, {r1, r3-r8, lr} + tst r2, #16 +- stmneia r0!, {r4-r7} +- ldmfd sp!, {r4-r7, lr} ++ stmneia ip!, {r4-r7} ++ ldmfd sp!, {r4-r8, lr} + + #endif + + 4: tst r2, #8 +- stmneia r0!, {r1, r3} ++ stmneia ip!, {r1, r3} + tst r2, #4 +- strne r1, [r0], #4 ++ strne r1, [ip], #4 + /* + * When we get here, we've got less than 4 bytes to zero. We + * may have an unaligned pointer as well. + */ + 5: tst r2, #2 +- strneb r1, [r0], #1 +- strneb r1, [r0], #1 ++ strneb r1, [ip], #1 ++ strneb r1, [ip], #1 + tst r2, #1 +- strneb r1, [r0], #1 ++ strneb r1, [ip], #1 + mov pc, lr ++ ++6: subs r2, r2, #4 @ 1 do we have enough ++ blt 5b @ 1 bytes to align with? ++ cmp r3, #2 @ 1 ++ strltb r1, [ip], #1 @ 1 ++ strleb r1, [ip], #1 @ 1 ++ strb r1, [ip], #1 @ 1 ++ add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3)) ++ b 1b + ENDPROC(memset) +diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h +index 9d7f1723..093bf0a2 100644 +--- a/drivers/net/xen-netback/common.h ++++ b/drivers/net/xen-netback/common.h +@@ -88,6 +88,7 @@ struct xenvif { + unsigned long credit_usec; + unsigned long remaining_credit; + struct timer_list credit_timeout; ++ u64 credit_window_start; + + /* Statistics */ + unsigned long rx_gso_checksum_fixup; +diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c +index 221f4265..cfaaf685 100644 +--- a/drivers/net/xen-netback/interface.c ++++ b/drivers/net/xen-netback/interface.c +@@ -273,8 +273,7 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, + vif->credit_bytes = vif->remaining_credit = ~0UL; + vif->credit_usec = 0UL; + init_timer(&vif->credit_timeout); +- /* Initialize 'expires' now: it's used to track the credit window. */ +- vif->credit_timeout.expires = jiffies; ++ vif->credit_window_start = get_jiffies_64(); + + dev->netdev_ops = &xenvif_netdev_ops; + dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO; +diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c +index 0d22cff0..d8ffbf84 100644 +--- a/drivers/net/xen-netback/netback.c ++++ b/drivers/net/xen-netback/netback.c +@@ -1197,9 +1197,8 @@ out: + + static bool tx_credit_exceeded(struct xenvif *vif, unsigned size) + { +- unsigned long now = jiffies; +- unsigned long next_credit = +- vif->credit_timeout.expires + ++ u64 now = get_jiffies_64(); ++ u64 next_credit = vif->credit_window_start + + msecs_to_jiffies(vif->credit_usec / 1000); + + /* Timer could already be pending in rare cases. */ +@@ -1207,8 +1206,8 @@ static bool tx_credit_exceeded(struct xenvif *vif, unsigned size) + return true; + + /* Passed the point where we can replenish credit? */ +- if (time_after_eq(now, next_credit)) { +- vif->credit_timeout.expires = now; ++ if (time_after_eq64(now, next_credit)) { ++ vif->credit_window_start = now; + tx_add_credit(vif); + } + +@@ -1220,6 +1219,7 @@ static bool tx_credit_exceeded(struct xenvif *vif, unsigned size) + tx_credit_callback; + mod_timer(&vif->credit_timeout, + next_credit); ++ vif->credit_window_start = next_credit; + + return true; + } +diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c +index 54fc9880..21b9ed1d 100644 +--- a/drivers/pci/pci-driver.c ++++ b/drivers/pci/pci-driver.c +@@ -680,6 +680,7 @@ static int pci_pm_suspend(struct device *dev) + goto Fixup; + } + ++ pci_dev->state_saved = false; + if (pm->suspend) { + pci_power_t prev = pci_dev->current_state; + int error; +@@ -826,6 +827,7 @@ static int pci_pm_freeze(struct device *dev) + return 0; + } + ++ pci_dev->state_saved = false; + if (pm->freeze) { + int error; + +@@ -914,6 +916,7 @@ static int pci_pm_poweroff(struct device *dev) + goto Fixup; + } + ++ pci_dev->state_saved = false; + if (pm->poweroff) { + int error; + +@@ -1032,6 +1035,7 @@ static int pci_pm_runtime_suspend(struct device *dev) + if (!pm || !pm->runtime_suspend) + return -ENOSYS; + ++ pci_dev->state_saved = false; + error = pm->runtime_suspend(dev); + suspend_report_result(pm->runtime_suspend, error); + if (error) +diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c +index eea85daf..be76ebac 100644 +--- a/drivers/pci/setup-res.c ++++ b/drivers/pci/setup-res.c +@@ -206,7 +206,8 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev, + return ret; + } + +-static int _pci_assign_resource(struct pci_dev *dev, int resno, int size, resource_size_t min_align) ++static int _pci_assign_resource(struct pci_dev *dev, int resno, ++ resource_size_t size, resource_size_t min_align) + { + struct resource *res = dev->resource + resno; + struct pci_bus *bus; +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index aa54fad7..82fce32c 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -1335,6 +1335,7 @@ static int hub_configure(struct usb_hub *hub, + return 0; + + fail: ++ hdev->maxchild = 0; + dev_err (hub_dev, "config failed, %s (err %d)\n", + message, ret); + /* hub_disconnect() frees urb and descriptor */ +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 57277bcc..a5477554 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1391,6 +1391,23 @@ static const struct usb_device_id option_ids[] = { + .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1426, 0xff, 0xff, 0xff), /* ZTE MF91 */ + .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, ++ { 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) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1545, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1546, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1547, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1565, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1566, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1567, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1589, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1590, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1591, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1592, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1594, 0xff, 0xff, 0xff) }, ++ { 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, 0x2003, 0xff, 0xff, 0xff) }, +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index 5dd96266..022940f0 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -590,9 +590,12 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, + if (isspace(ch)) { + parser->buffer[parser->idx] = 0; + parser->cont = false; +- } else { ++ } else if (parser->idx < parser->size - 1) { + parser->cont = true; + parser->buffer[parser->idx++] = ch; ++ } else { ++ ret = -EINVAL; ++ goto out; + } + + *ppos += read; +diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c +index 27747881..200707c6 100644 +--- a/net/core/flow_dissector.c ++++ b/net/core/flow_dissector.c +@@ -35,7 +35,7 @@ again: + struct iphdr _iph; + ip: + iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph); +- if (!iph) ++ if (!iph || iph->ihl < 5) + return false; + + if (ip_is_fragment(iph)) +diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c +index 93faf6a3..4a8c55bd 100644 +--- a/net/netfilter/nf_conntrack_sip.c ++++ b/net/netfilter/nf_conntrack_sip.c +@@ -1468,7 +1468,7 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff, + + msglen = origlen = end - dptr; + if (msglen > datalen) +- return NF_DROP; ++ return NF_ACCEPT; + + ret = process_sip_msg(skb, ct, dataoff, &dptr, &msglen); + if (ret != NF_ACCEPT) +diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c +index 02a6e3f4..ef917bf2 100644 +--- a/sound/pci/hda/patch_hdmi.c ++++ b/sound/pci/hda/patch_hdmi.c +@@ -1282,23 +1282,34 @@ static int generic_hdmi_build_controls(struct hda_codec *codec) + return 0; + } + +-static int generic_hdmi_init(struct hda_codec *codec) ++static int generic_hdmi_init_per_pins(struct hda_codec *codec) + { + struct hdmi_spec *spec = codec->spec; + int pin_idx; + + for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { + struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; +- hda_nid_t pin_nid = per_pin->pin_nid; + struct hdmi_eld *eld = &per_pin->sink_eld; + +- hdmi_init_pin(codec, pin_nid); +- snd_hda_jack_detect_enable(codec, pin_nid, pin_nid); +- + per_pin->codec = codec; + INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld); + snd_hda_eld_proc_new(codec, eld, pin_idx); + } ++ return 0; ++} ++ ++static int generic_hdmi_init(struct hda_codec *codec) ++{ ++ struct hdmi_spec *spec = codec->spec; ++ int pin_idx; ++ ++ for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { ++ struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; ++ hda_nid_t pin_nid = per_pin->pin_nid; ++ ++ hdmi_init_pin(codec, pin_nid); ++ snd_hda_jack_detect_enable(codec, pin_nid, pin_nid); ++ } + snd_hda_jack_report_sync(codec); + return 0; + } +@@ -1343,6 +1354,7 @@ static int patch_generic_hdmi(struct hda_codec *codec) + return -EINVAL; + } + codec->patch_ops = generic_hdmi_patch_ops; ++ generic_hdmi_init_per_pins(codec); + + init_channel_allocations(); + diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.70-71.patch b/patch/kernel/sun8i-default/0001-patch-3.4.70-71.patch new file mode 100644 index 000000000..f0ec780bb --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.70-71.patch @@ -0,0 +1,1738 @@ +diff --git a/Makefile b/Makefile +index d7c0a3833a2b..05ace57061d6 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 70 ++SUBLEVEL = 71 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/cris/include/asm/io.h b/arch/cris/include/asm/io.h +index ac12ae2b9286..db9a16c704f3 100644 +--- a/arch/cris/include/asm/io.h ++++ b/arch/cris/include/asm/io.h +@@ -3,6 +3,7 @@ + + #include /* for __va, __pa */ + #include ++#include + #include + + struct cris_io_operations +diff --git a/arch/ia64/include/asm/processor.h b/arch/ia64/include/asm/processor.h +index 483f6c6a4238..2d0cb8e8eedd 100644 +--- a/arch/ia64/include/asm/processor.h ++++ b/arch/ia64/include/asm/processor.h +@@ -322,7 +322,7 @@ struct thread_struct { + regs->loadrs = 0; \ + regs->r8 = get_dumpable(current->mm); /* set "don't zap registers" flag */ \ + regs->r12 = new_sp - 16; /* allocate 16 byte scratch area */ \ +- if (unlikely(!get_dumpable(current->mm))) { \ ++ if (unlikely(get_dumpable(current->mm) != SUID_DUMP_USER)) { \ + /* \ + * Zap scratch regs to avoid leaking bits between processes with different \ + * uid/privileges. \ +diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c +index 45eb998557f8..e6de787956ce 100644 +--- a/arch/powerpc/kernel/signal_32.c ++++ b/arch/powerpc/kernel/signal_32.c +@@ -459,7 +459,15 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, + if (copy_vsx_to_user(&frame->mc_vsregs, current)) + return 1; + msr |= MSR_VSX; +- } ++ } else if (!ctx_has_vsx_region) ++ /* ++ * With a small context structure we can't hold the VSX ++ * registers, hence clear the MSR value to indicate the state ++ * was not saved. ++ */ ++ msr &= ~MSR_VSX; ++ ++ + #endif /* CONFIG_VSX */ + #ifdef CONFIG_SPE + /* save spe registers */ +diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c +index cfe0069bcfc8..fcf89bff1177 100644 +--- a/arch/powerpc/kernel/vio.c ++++ b/arch/powerpc/kernel/vio.c +@@ -1342,12 +1342,12 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, + + dn = dev->of_node; + if (!dn) { +- strcat(buf, "\n"); ++ strcpy(buf, "\n"); + return strlen(buf); + } + cp = of_get_property(dn, "compatible", NULL); + if (!cp) { +- strcat(buf, "\n"); ++ strcpy(buf, "\n"); + return strlen(buf); + } + +diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c +index fbdd74dac3ac..5da8e8df5922 100644 +--- a/arch/powerpc/platforms/powernv/pci-ioda.c ++++ b/arch/powerpc/platforms/powernv/pci-ioda.c +@@ -613,13 +613,23 @@ static int __devinit pnv_ioda_configure_pe(struct pnv_phb *phb, + rid_end = pe->rid + 1; + } + +- /* Associate PE in PELT */ ++ /* ++ * Associate PE in PELT. We need add the PE into the ++ * corresponding PELT-V as well. Otherwise, the error ++ * originated from the PE might contribute to other ++ * PEs. ++ */ + rc = opal_pci_set_pe(phb->opal_id, pe->pe_number, pe->rid, + bcomp, dcomp, fcomp, OPAL_MAP_PE); + if (rc) { + pe_err(pe, "OPAL error %ld trying to setup PELT table\n", rc); + return -ENXIO; + } ++ ++ rc = opal_pci_set_peltv(phb->opal_id, pe->pe_number, ++ pe->pe_number, OPAL_ADD_PE_TO_DOMAIN); ++ if (rc) ++ pe_warn(pe, "OPAL error %d adding self to PELTV\n", rc); + opal_pci_eeh_freeze_clear(phb->opal_id, pe->pe_number, + OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); + +diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c +index 5d8cf0d6796c..b316ffe8ab59 100644 +--- a/arch/x86/kernel/microcode_amd.c ++++ b/arch/x86/kernel/microcode_amd.c +@@ -338,7 +338,7 @@ static enum ucode_state request_microcode_amd(int cpu, struct device *device) + snprintf(fw_name, sizeof(fw_name), "amd-ucode/microcode_amd_fam%.2xh.bin", c->x86); + + if (request_firmware(&fw, (const char *)fw_name, device)) { +- pr_err("failed to load file %s\n", fw_name); ++ pr_debug("failed to load file %s\n", fw_name); + goto out; + } + +diff --git a/block/blk-core.c b/block/blk-core.c +index 85fd41003434..a02cfb7e4123 100644 +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -2041,6 +2041,7 @@ void blk_start_request(struct request *req) + if (unlikely(blk_bidi_rq(req))) + req->next_rq->resid_len = blk_rq_bytes(req->next_rq); + ++ BUG_ON(test_bit(REQ_ATOM_COMPLETE, &req->atomic_flags)); + blk_add_timer(req); + } + EXPORT_SYMBOL(blk_start_request); +diff --git a/block/blk-settings.c b/block/blk-settings.c +index d3234fc494ad..b74cc58bc038 100644 +--- a/block/blk-settings.c ++++ b/block/blk-settings.c +@@ -143,6 +143,7 @@ void blk_set_stacking_limits(struct queue_limits *lim) + lim->discard_zeroes_data = 1; + lim->max_segments = USHRT_MAX; + lim->max_hw_sectors = UINT_MAX; ++ lim->max_segment_size = UINT_MAX; + + lim->max_sectors = BLK_DEF_MAX_SECTORS; + } +diff --git a/block/blk-timeout.c b/block/blk-timeout.c +index 780354888958..b1182ea52427 100644 +--- a/block/blk-timeout.c ++++ b/block/blk-timeout.c +@@ -90,8 +90,8 @@ static void blk_rq_timed_out(struct request *req) + __blk_complete_request(req); + break; + case BLK_EH_RESET_TIMER: +- blk_clear_rq_complete(req); + blk_add_timer(req); ++ blk_clear_rq_complete(req); + break; + case BLK_EH_NOT_HANDLED: + /* +@@ -173,7 +173,6 @@ void blk_add_timer(struct request *req) + return; + + BUG_ON(!list_empty(&req->timeout_list)); +- BUG_ON(test_bit(REQ_ATOM_COMPLETE, &req->atomic_flags)); + + /* + * Some LLDs, like scsi, peek at the timeout to prevent a +diff --git a/crypto/ansi_cprng.c b/crypto/ansi_cprng.c +index 6ddd99e6114b..c21f761b65b5 100644 +--- a/crypto/ansi_cprng.c ++++ b/crypto/ansi_cprng.c +@@ -230,11 +230,11 @@ remainder: + */ + if (byte_count < DEFAULT_BLK_SZ) { + empty_rbuf: +- for (; ctx->rand_data_valid < DEFAULT_BLK_SZ; +- ctx->rand_data_valid++) { ++ while (ctx->rand_data_valid < DEFAULT_BLK_SZ) { + *ptr = ctx->rand_data[ctx->rand_data_valid]; + ptr++; + byte_count--; ++ ctx->rand_data_valid++; + if (byte_count == 0) + goto done; + } +diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c +index 9ba8c73cea16..fe2f9d95d0f8 100644 +--- a/drivers/acpi/acpica/exoparg1.c ++++ b/drivers/acpi/acpica/exoparg1.c +@@ -970,10 +970,17 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) + */ + return_desc = + *(operand[0]->reference.where); +- if (return_desc) { +- acpi_ut_add_reference +- (return_desc); ++ if (!return_desc) { ++ /* ++ * Element is NULL, do not allow the dereference. ++ * This provides compatibility with other ACPI ++ * implementations. ++ */ ++ return_ACPI_STATUS ++ (AE_AML_UNINITIALIZED_ELEMENT); + } ++ ++ acpi_ut_add_reference(return_desc); + break; + + default: +@@ -998,11 +1005,40 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) + acpi_namespace_node + *) + return_desc); +- } ++ if (!return_desc) { ++ break; ++ } + +- /* Add another reference to the object! */ ++ /* ++ * June 2013: ++ * buffer_fields/field_units require additional resolution ++ */ ++ switch (return_desc->common.type) { ++ case ACPI_TYPE_BUFFER_FIELD: ++ case ACPI_TYPE_LOCAL_REGION_FIELD: ++ case ACPI_TYPE_LOCAL_BANK_FIELD: ++ case ACPI_TYPE_LOCAL_INDEX_FIELD: + +- acpi_ut_add_reference(return_desc); ++ status = ++ acpi_ex_read_data_from_field ++ (walk_state, return_desc, ++ &temp_desc); ++ if (ACPI_FAILURE(status)) { ++ goto cleanup; ++ } ++ ++ return_desc = temp_desc; ++ break; ++ ++ default: ++ ++ /* Add another reference to the object */ ++ ++ acpi_ut_add_reference ++ (return_desc); ++ break; ++ } ++ } + break; + + default: +diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c +index c6cf843cc4c9..9806f4be7b88 100644 +--- a/drivers/acpi/acpica/exstore.c ++++ b/drivers/acpi/acpica/exstore.c +@@ -57,6 +57,11 @@ acpi_ex_store_object_to_index(union acpi_operand_object *val_desc, + union acpi_operand_object *dest_desc, + struct acpi_walk_state *walk_state); + ++static acpi_status ++acpi_ex_store_direct_to_node(union acpi_operand_object *source_desc, ++ struct acpi_namespace_node *node, ++ struct acpi_walk_state *walk_state); ++ + /******************************************************************************* + * + * FUNCTION: acpi_ex_store +@@ -376,7 +381,11 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, + * When storing into an object the data is converted to the + * target object type then stored in the object. This means + * that the target object type (for an initialized target) will +- * not be changed by a store operation. ++ * not be changed by a store operation. A copy_object can change ++ * the target type, however. ++ * ++ * The implicit_conversion flag is set to NO/FALSE only when ++ * storing to an arg_x -- as per the rules of the ACPI spec. + * + * Assumes parameters are already validated. + * +@@ -400,7 +409,7 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, + target_type = acpi_ns_get_type(node); + target_desc = acpi_ns_get_attached_object(node); + +- ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p(%s) into node %p(%s)\n", ++ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p (%s) to node %p (%s)\n", + source_desc, + acpi_ut_get_object_type_name(source_desc), node, + acpi_ut_get_type_name(target_type))); +@@ -414,46 +423,31 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, + return_ACPI_STATUS(status); + } + +- /* If no implicit conversion, drop into the default case below */ +- +- if ((!implicit_conversion) || +- ((walk_state->opcode == AML_COPY_OP) && +- (target_type != ACPI_TYPE_LOCAL_REGION_FIELD) && +- (target_type != ACPI_TYPE_LOCAL_BANK_FIELD) && +- (target_type != ACPI_TYPE_LOCAL_INDEX_FIELD))) { +- /* +- * Force execution of default (no implicit conversion). Note: +- * copy_object does not perform an implicit conversion, as per the ACPI +- * spec -- except in case of region/bank/index fields -- because these +- * objects must retain their original type permanently. +- */ +- target_type = ACPI_TYPE_ANY; +- } +- + /* Do the actual store operation */ + + switch (target_type) { +- case ACPI_TYPE_BUFFER_FIELD: +- case ACPI_TYPE_LOCAL_REGION_FIELD: +- case ACPI_TYPE_LOCAL_BANK_FIELD: +- case ACPI_TYPE_LOCAL_INDEX_FIELD: +- +- /* For fields, copy the source data to the target field. */ +- +- status = acpi_ex_write_data_to_field(source_desc, target_desc, +- &walk_state->result_obj); +- break; +- + case ACPI_TYPE_INTEGER: + case ACPI_TYPE_STRING: + case ACPI_TYPE_BUFFER: + + /* +- * These target types are all of type Integer/String/Buffer, and +- * therefore support implicit conversion before the store. +- * +- * Copy and/or convert the source object to a new target object ++ * The simple data types all support implicit source operand ++ * conversion before the store. + */ ++ ++ if ((walk_state->opcode == AML_COPY_OP) || !implicit_conversion) { ++ /* ++ * However, copy_object and Stores to arg_x do not perform ++ * an implicit conversion, as per the ACPI specification. ++ * A direct store is performed instead. ++ */ ++ status = acpi_ex_store_direct_to_node(source_desc, node, ++ walk_state); ++ break; ++ } ++ ++ /* Store with implicit source operand conversion support */ ++ + status = + acpi_ex_store_object_to_object(source_desc, target_desc, + &new_desc, walk_state); +@@ -467,13 +461,12 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, + * the Name's type to that of the value being stored in it. + * source_desc reference count is incremented by attach_object. + * +- * Note: This may change the type of the node if an explicit store +- * has been performed such that the node/object type has been +- * changed. ++ * Note: This may change the type of the node if an explicit ++ * store has been performed such that the node/object type ++ * has been changed. + */ +- status = +- acpi_ns_attach_object(node, new_desc, +- new_desc->common.type); ++ status = acpi_ns_attach_object(node, new_desc, ++ new_desc->common.type); + + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, + "Store %s into %s via Convert/Attach\n", +@@ -484,19 +477,83 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, + } + break; + ++ case ACPI_TYPE_BUFFER_FIELD: ++ case ACPI_TYPE_LOCAL_REGION_FIELD: ++ case ACPI_TYPE_LOCAL_BANK_FIELD: ++ case ACPI_TYPE_LOCAL_INDEX_FIELD: ++ /* ++ * For all fields, always write the source data to the target ++ * field. Any required implicit source operand conversion is ++ * performed in the function below as necessary. Note, field ++ * objects must retain their original type permanently. ++ */ ++ status = acpi_ex_write_data_to_field(source_desc, target_desc, ++ &walk_state->result_obj); ++ break; ++ + default: ++ /* ++ * No conversions for all other types. Directly store a copy of ++ * the source object. This is the ACPI spec-defined behavior for ++ * the copy_object operator. ++ * ++ * NOTE: For the Store operator, this is a departure from the ++ * ACPI spec, which states "If conversion is impossible, abort ++ * the running control method". Instead, this code implements ++ * "If conversion is impossible, treat the Store operation as ++ * a CopyObject". ++ */ ++ status = acpi_ex_store_direct_to_node(source_desc, node, ++ walk_state); ++ break; ++ } + +- ACPI_DEBUG_PRINT((ACPI_DB_EXEC, +- "Storing %s (%p) directly into node (%p) with no implicit conversion\n", +- acpi_ut_get_object_type_name(source_desc), +- source_desc, node)); ++ return_ACPI_STATUS(status); ++} + +- /* No conversions for all other types. Just attach the source object */ ++/******************************************************************************* ++ * ++ * FUNCTION: acpi_ex_store_direct_to_node ++ * ++ * PARAMETERS: source_desc - Value to be stored ++ * node - Named object to receive the value ++ * walk_state - Current walk state ++ * ++ * RETURN: Status ++ * ++ * DESCRIPTION: "Store" an object directly to a node. This involves a copy ++ * and an attach. ++ * ++ ******************************************************************************/ + +- status = acpi_ns_attach_object(node, source_desc, +- source_desc->common.type); +- break; ++static acpi_status ++acpi_ex_store_direct_to_node(union acpi_operand_object *source_desc, ++ struct acpi_namespace_node *node, ++ struct acpi_walk_state *walk_state) ++{ ++ acpi_status status; ++ union acpi_operand_object *new_desc; ++ ++ ACPI_FUNCTION_TRACE(ex_store_direct_to_node); ++ ++ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, ++ "Storing [%s] (%p) directly into node [%s] (%p)" ++ " with no implicit conversion\n", ++ acpi_ut_get_object_type_name(source_desc), ++ source_desc, acpi_ut_get_type_name(node->type), ++ node)); ++ ++ /* Copy the source object to a new object */ ++ ++ status = ++ acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc, walk_state); ++ if (ACPI_FAILURE(status)) { ++ return_ACPI_STATUS(status); + } + ++ /* Attach the new object to the node */ ++ ++ status = acpi_ns_attach_object(node, new_desc, new_desc->common.type); ++ acpi_ut_remove_reference(new_desc); + return_ACPI_STATUS(status); + } +diff --git a/drivers/block/brd.c b/drivers/block/brd.c +index 4e8213aa02fd..a7d70e2a8d74 100644 +--- a/drivers/block/brd.c ++++ b/drivers/block/brd.c +@@ -546,7 +546,7 @@ static struct kobject *brd_probe(dev_t dev, int *part, void *data) + + mutex_lock(&brd_devices_mutex); + brd = brd_init_one(MINOR(dev) >> part_shift); +- kobj = brd ? get_disk(brd->brd_disk) : ERR_PTR(-ENOMEM); ++ kobj = brd ? get_disk(brd->brd_disk) : NULL; + mutex_unlock(&brd_devices_mutex); + + *part = 0; +diff --git a/drivers/block/loop.c b/drivers/block/loop.c +index 179b5b408cb3..a4ddbae2e100 100644 +--- a/drivers/block/loop.c ++++ b/drivers/block/loop.c +@@ -1743,7 +1743,7 @@ static struct kobject *loop_probe(dev_t dev, int *part, void *data) + if (err < 0) + err = loop_add(&lo, MINOR(dev) >> part_shift); + if (err < 0) +- kobj = ERR_PTR(err); ++ kobj = NULL; + else + kobj = get_disk(lo->lo_disk); + mutex_unlock(&loop_index_mutex); +diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c +index 22b14a68e35e..1f4f94103c55 100644 +--- a/drivers/hwmon/lm90.c ++++ b/drivers/hwmon/lm90.c +@@ -278,7 +278,7 @@ static const struct lm90_params lm90_params[] = { + [max6696] = { + .flags = LM90_HAVE_EMERGENCY + | LM90_HAVE_EMERGENCY_ALARM | LM90_HAVE_TEMP3, +- .alert_alarms = 0x187c, ++ .alert_alarms = 0x1c7c, + .max_convrate = 6, + .reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL, + }, +@@ -1504,19 +1504,22 @@ static void lm90_alert(struct i2c_client *client, unsigned int flag) + if ((alarms & 0x7f) == 0 && (alarms2 & 0xfe) == 0) { + dev_info(&client->dev, "Everything OK\n"); + } else { +- if (alarms & 0x61) ++ if ((alarms & 0x61) || (alarms2 & 0x80)) + dev_warn(&client->dev, + "temp%d out of range, please check!\n", 1); +- if (alarms & 0x1a) ++ if ((alarms & 0x1a) || (alarms2 & 0x20)) + dev_warn(&client->dev, + "temp%d out of range, please check!\n", 2); + if (alarms & 0x04) + dev_warn(&client->dev, + "temp%d diode open, please check!\n", 2); + +- if (alarms2 & 0x18) ++ if (alarms2 & 0x5a) + dev_warn(&client->dev, + "temp%d out of range, please check!\n", 3); ++ if (alarms2 & 0x04) ++ dev_warn(&client->dev, ++ "temp%d diode open, please check!\n", 3); + + /* + * Disable ALERT# output, because these chips don't implement +diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c +index 21a3d77ea7e2..77405b4e8636 100644 +--- a/drivers/net/can/c_can/c_can.c ++++ b/drivers/net/can/c_can/c_can.c +@@ -760,9 +760,6 @@ static int c_can_do_rx_poll(struct net_device *dev, int quota) + msg_ctrl_save = priv->read_reg(priv, + &priv->regs->ifregs[0].msg_cntrl); + +- if (msg_ctrl_save & IF_MCONT_EOB) +- return num_rx_pkts; +- + if (msg_ctrl_save & IF_MCONT_MSGLST) { + c_can_handle_lost_msg_obj(dev, 0, msg_obj); + num_rx_pkts++; +@@ -770,6 +767,9 @@ static int c_can_do_rx_poll(struct net_device *dev, int quota) + continue; + } + ++ if (msg_ctrl_save & IF_MCONT_EOB) ++ return num_rx_pkts; ++ + if (!(msg_ctrl_save & IF_MCONT_NEWDAT)) + continue; + +diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c +index 1b4404725b8c..effb3b71ce75 100644 +--- a/drivers/net/ethernet/realtek/8139cp.c ++++ b/drivers/net/ethernet/realtek/8139cp.c +@@ -1232,6 +1232,7 @@ static void cp_tx_timeout(struct net_device *dev) + cp_clean_rings(cp); + rc = cp_init_rings(cp); + cp_start_hw(cp); ++ cp_enable_irq(cp); + + netif_wake_queue(dev); + +diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c +index a06cc283e23d..0b48430d6ad0 100644 +--- a/drivers/net/wireless/libertas/debugfs.c ++++ b/drivers/net/wireless/libertas/debugfs.c +@@ -913,7 +913,10 @@ static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf, + char *p2; + struct debug_data *d = f->private_data; + +- pdata = kmalloc(cnt, GFP_KERNEL); ++ if (cnt == 0) ++ return 0; ++ ++ pdata = kmalloc(cnt + 1, GFP_KERNEL); + if (pdata == NULL) + return 0; + +@@ -922,6 +925,7 @@ static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf, + kfree(pdata); + return 0; + } ++ pdata[cnt] = '\0'; + + p0 = pdata; + for (i = 0; i < num_of_items; i++) { +diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c +index 65cb4250259f..6eec862fea28 100644 +--- a/drivers/net/wireless/rt2x00/rt2800usb.c ++++ b/drivers/net/wireless/rt2x00/rt2800usb.c +@@ -143,6 +143,8 @@ static bool rt2800usb_txstatus_timeout(struct rt2x00_dev *rt2x00dev) + return false; + } + ++#define TXSTATUS_READ_INTERVAL 1000000 ++ + static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, + int urb_status, u32 tx_status) + { +@@ -170,8 +172,9 @@ static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, + queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); + + if (rt2800usb_txstatus_pending(rt2x00dev)) { +- /* Read register after 250 us */ +- hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 250000), ++ /* Read register after 1 ms */ ++ hrtimer_start(&rt2x00dev->txstatus_timer, ++ ktime_set(0, TXSTATUS_READ_INTERVAL), + HRTIMER_MODE_REL); + return false; + } +@@ -196,8 +199,9 @@ static void rt2800usb_async_read_tx_status(struct rt2x00_dev *rt2x00dev) + if (test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags)) + return; + +- /* Read TX_STA_FIFO register after 500 us */ +- hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 500000), ++ /* Read TX_STA_FIFO register after 2 ms */ ++ hrtimer_start(&rt2x00dev->txstatus_timer, ++ ktime_set(0, 2*TXSTATUS_READ_INTERVAL), + HRTIMER_MODE_REL); + } + +diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c +index a8885f060060..6701f2d71274 100644 +--- a/drivers/net/wireless/rt2x00/rt2x00mac.c ++++ b/drivers/net/wireless/rt2x00/rt2x00mac.c +@@ -771,6 +771,9 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop) + struct rt2x00_dev *rt2x00dev = hw->priv; + struct data_queue *queue; + ++ if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) ++ return; ++ + tx_queue_for_each(rt2x00dev, queue) + rt2x00queue_flush_queue(queue, drop); + } +diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c +index 0bd38da4ada0..05fbc3ded9b5 100644 +--- a/drivers/scsi/aacraid/commctrl.c ++++ b/drivers/scsi/aacraid/commctrl.c +@@ -508,7 +508,8 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) + goto cleanup; + } + +- if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))) { ++ if ((fibsize < (sizeof(struct user_aac_srb) - sizeof(struct user_sgentry))) || ++ (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr)))) { + rcode = -EINVAL; + goto cleanup; + } +diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c +index a783d533a1a6..715075291834 100644 +--- a/drivers/uio/uio.c ++++ b/drivers/uio/uio.c +@@ -650,16 +650,30 @@ static int uio_mmap_physical(struct vm_area_struct *vma) + { + struct uio_device *idev = vma->vm_private_data; + int mi = uio_find_mem_index(vma); ++ struct uio_mem *mem; + if (mi < 0) + return -EINVAL; ++ mem = idev->info->mem + mi; ++ ++ if (vma->vm_end - vma->vm_start > mem->size) ++ return -EINVAL; + + vma->vm_flags |= VM_IO | VM_RESERVED; + + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + ++ /* ++ * We cannot use the vm_iomap_memory() helper here, ++ * because vma->vm_pgoff is the map index we looked ++ * up above in uio_find_mem_index(), rather than an ++ * actual page offset into the mmap. ++ * ++ * So we just do the physical mmap without a page ++ * offset. ++ */ + return remap_pfn_range(vma, + vma->vm_start, +- idev->info->mem[mi].addr >> PAGE_SHIFT, ++ mem->addr >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot); + } +diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c +index c8542356898b..91293b68df5a 100644 +--- a/drivers/usb/serial/mos7840.c ++++ b/drivers/usb/serial/mos7840.c +@@ -1664,7 +1664,11 @@ static int mos7840_tiocmget(struct tty_struct *tty) + return -ENODEV; + + status = mos7840_get_uart_reg(port, MODEM_STATUS_REGISTER, &msr); ++ if (status != 1) ++ return -EIO; + status = mos7840_get_uart_reg(port, MODEM_CONTROL_REGISTER, &mcr); ++ if (status != 1) ++ return -EIO; + result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0) + | ((mcr & MCR_RTS) ? TIOCM_RTS : 0) + | ((mcr & MCR_LOOPBACK) ? TIOCM_LOOP : 0) +diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c +index ffbce4525468..612c1c7cb31b 100644 +--- a/drivers/video/au1100fb.c ++++ b/drivers/video/au1100fb.c +@@ -375,39 +375,15 @@ void au1100fb_fb_rotate(struct fb_info *fbi, int angle) + int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) + { + struct au1100fb_device *fbdev; +- unsigned int len; +- unsigned long start=0, off; + + fbdev = to_au1100fb_device(fbi); + +- if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) { +- return -EINVAL; +- } +- +- start = fbdev->fb_phys & PAGE_MASK; +- len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len); +- +- off = vma->vm_pgoff << PAGE_SHIFT; +- +- if ((vma->vm_end - vma->vm_start + off) > len) { +- return -EINVAL; +- } +- +- off += start; +- vma->vm_pgoff = off >> PAGE_SHIFT; +- + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + pgprot_val(vma->vm_page_prot) |= (6 << 9); //CCA=6 + + vma->vm_flags |= VM_IO; + +- if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, +- vma->vm_end - vma->vm_start, +- vma->vm_page_prot)) { +- return -EAGAIN; +- } +- +- return 0; ++ return vm_iomap_memory(vma, fbdev->fb_phys, fbdev->fb_len); + } + + static struct fb_ops au1100fb_ops = +diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c +index 7ca79f02056e..117be3d9b854 100644 +--- a/drivers/video/au1200fb.c ++++ b/drivers/video/au1200fb.c +@@ -1233,36 +1233,15 @@ static int au1200fb_fb_blank(int blank_mode, struct fb_info *fbi) + * method mainly to allow the use of the TLB streaming flag (CCA=6) + */ + static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) +- + { +- unsigned int len; +- unsigned long start=0, off; + struct au1200fb_device *fbdev = info->par; + +- if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) { +- return -EINVAL; +- } +- +- start = fbdev->fb_phys & PAGE_MASK; +- len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len); +- +- off = vma->vm_pgoff << PAGE_SHIFT; +- +- if ((vma->vm_end - vma->vm_start + off) > len) { +- return -EINVAL; +- } +- +- off += start; +- vma->vm_pgoff = off >> PAGE_SHIFT; +- + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + pgprot_val(vma->vm_page_prot) |= _CACHE_MASK; /* CCA=7 */ + + vma->vm_flags |= VM_IO; + +- return io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, +- vma->vm_end - vma->vm_start, +- vma->vm_page_prot); ++ return vm_iomap_memory(vma, fbdev->fb_phys, fbdev->fb_len); + + return 0; + } +diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c +index 7e6c52d8a207..c91f6d1bf64f 100644 +--- a/fs/configfs/dir.c ++++ b/fs/configfs/dir.c +@@ -56,10 +56,19 @@ static void configfs_d_iput(struct dentry * dentry, + struct configfs_dirent *sd = dentry->d_fsdata; + + if (sd) { +- BUG_ON(sd->s_dentry != dentry); + /* Coordinate with configfs_readdir */ + spin_lock(&configfs_dirent_lock); +- sd->s_dentry = NULL; ++ /* Coordinate with configfs_attach_attr where will increase ++ * sd->s_count and update sd->s_dentry to new allocated one. ++ * Only set sd->dentry to null when this dentry is the only ++ * sd owner. ++ * If not do so, configfs_d_iput may run just after ++ * configfs_attach_attr and set sd->s_dentry to null ++ * even it's still in use. ++ */ ++ if (atomic_read(&sd->s_count) <= 2) ++ sd->s_dentry = NULL; ++ + spin_unlock(&configfs_dirent_lock); + configfs_put(sd); + } +@@ -426,8 +435,11 @@ static int configfs_attach_attr(struct configfs_dirent * sd, struct dentry * den + struct configfs_attribute * attr = sd->s_element; + int error; + ++ spin_lock(&configfs_dirent_lock); + dentry->d_fsdata = configfs_get(sd); + sd->s_dentry = dentry; ++ spin_unlock(&configfs_dirent_lock); ++ + error = configfs_create(dentry, (attr->ca_mode & S_IALLUGO) | S_IFREG, + configfs_init_file); + if (error) { +diff --git a/fs/dcache.c b/fs/dcache.c +index 9d39de40909d..09e2eda55c57 100644 +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -2513,7 +2513,6 @@ static int prepend_path(const struct path *path, + bool slash = false; + int error = 0; + +- br_read_lock(vfsmount_lock); + while (dentry != root->dentry || vfsmnt != root->mnt) { + struct dentry * parent; + +@@ -2543,8 +2542,6 @@ static int prepend_path(const struct path *path, + if (!error && !slash) + error = prepend(buffer, buflen, "/", 1); + +-out: +- br_read_unlock(vfsmount_lock); + return error; + + global_root: +@@ -2561,7 +2558,7 @@ global_root: + error = prepend(buffer, buflen, "/", 1); + if (!error) + error = real_mount(vfsmnt)->mnt_ns ? 1 : 2; +- goto out; ++ return error; + } + + /** +@@ -2588,9 +2585,11 @@ char *__d_path(const struct path *path, + int error; + + prepend(&res, &buflen, "\0", 1); ++ br_read_lock(vfsmount_lock); + write_seqlock(&rename_lock); + error = prepend_path(path, root, &res, &buflen); + write_sequnlock(&rename_lock); ++ br_read_unlock(vfsmount_lock); + + if (error < 0) + return ERR_PTR(error); +@@ -2607,9 +2606,11 @@ char *d_absolute_path(const struct path *path, + int error; + + prepend(&res, &buflen, "\0", 1); ++ br_read_lock(vfsmount_lock); + write_seqlock(&rename_lock); + error = prepend_path(path, &root, &res, &buflen); + write_sequnlock(&rename_lock); ++ br_read_unlock(vfsmount_lock); + + if (error > 1) + error = -EINVAL; +@@ -2673,11 +2674,13 @@ char *d_path(const struct path *path, char *buf, int buflen) + return path->dentry->d_op->d_dname(path->dentry, buf, buflen); + + get_fs_root(current->fs, &root); ++ br_read_lock(vfsmount_lock); + write_seqlock(&rename_lock); + error = path_with_deleted(path, &root, &res, &buflen); ++ write_sequnlock(&rename_lock); ++ br_read_unlock(vfsmount_lock); + if (error < 0) + res = ERR_PTR(error); +- write_sequnlock(&rename_lock); + path_put(&root); + return res; + } +@@ -2832,6 +2835,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size) + get_fs_root_and_pwd(current->fs, &root, &pwd); + + error = -ENOENT; ++ br_read_lock(vfsmount_lock); + write_seqlock(&rename_lock); + if (!d_unlinked(pwd.dentry)) { + unsigned long len; +@@ -2841,6 +2845,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size) + prepend(&cwd, &buflen, "\0", 1); + error = prepend_path(&pwd, &root, &cwd, &buflen); + write_sequnlock(&rename_lock); ++ br_read_unlock(vfsmount_lock); + + if (error < 0) + goto out; +@@ -2861,6 +2866,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size) + } + } else { + write_sequnlock(&rename_lock); ++ br_read_unlock(vfsmount_lock); + } + + out: +diff --git a/fs/exec.c b/fs/exec.c +index 0ea0b4c476d8..5b9dfbe84b19 100644 +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -909,11 +909,13 @@ static int de_thread(struct task_struct *tsk) + + sig->notify_count = -1; /* for exit_notify() */ + for (;;) { ++ threadgroup_change_begin(tsk); + write_lock_irq(&tasklist_lock); + if (likely(leader->exit_state)) + break; + __set_current_state(TASK_UNINTERRUPTIBLE); + write_unlock_irq(&tasklist_lock); ++ threadgroup_change_end(tsk); + schedule(); + } + +@@ -969,6 +971,7 @@ static int de_thread(struct task_struct *tsk) + if (unlikely(leader->ptrace)) + __wake_up_parent(leader, leader->parent); + write_unlock_irq(&tasklist_lock); ++ threadgroup_change_end(tsk); + + release_task(leader); + } +@@ -2024,6 +2027,12 @@ static int __get_dumpable(unsigned long mm_flags) + return (ret >= 2) ? 2 : ret; + } + ++/* ++ * This returns the actual value of the suid_dumpable flag. For things ++ * that are using this for checking for privilege transitions, it must ++ * test against SUID_DUMP_USER rather than treating it as a boolean ++ * value. ++ */ + int get_dumpable(struct mm_struct *mm) + { + return __get_dumpable(mm->flags); +diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c +index edf411988bf3..9bb4e5c541b0 100644 +--- a/fs/nfs/inode.c ++++ b/fs/nfs/inode.c +@@ -224,6 +224,8 @@ nfs_find_actor(struct inode *inode, void *opaque) + + if (NFS_FILEID(inode) != fattr->fileid) + return 0; ++ if ((S_IFMT & inode->i_mode) != (S_IFMT & fattr->mode)) ++ return 0; + if (nfs_compare_fh(NFS_FH(inode), fh)) + return 0; + if (is_bad_inode(inode) || NFS_STALE(inode)) +diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c +index a7a043d272da..51017baa67af 100644 +--- a/fs/nfs/nfs3proc.c ++++ b/fs/nfs/nfs3proc.c +@@ -24,14 +24,14 @@ + + #define NFSDBG_FACILITY NFSDBG_PROC + +-/* A wrapper to handle the EJUKEBOX and EKEYEXPIRED error messages */ ++/* A wrapper to handle the EJUKEBOX error messages */ + static int + nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags) + { + int res; + do { + res = rpc_call_sync(clnt, msg, flags); +- if (res != -EJUKEBOX && res != -EKEYEXPIRED) ++ if (res != -EJUKEBOX) + break; + freezable_schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME); + res = -ERESTARTSYS; +@@ -44,7 +44,7 @@ nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags) + static int + nfs3_async_handle_jukebox(struct rpc_task *task, struct inode *inode) + { +- if (task->tk_status != -EJUKEBOX && task->tk_status != -EKEYEXPIRED) ++ if (task->tk_status != -EJUKEBOX) + return 0; + if (task->tk_status == -EJUKEBOX) + nfs_inc_stats(inode, NFSIOS_DELAY); +diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c +index 5acfd9ea8a31..4d64d5b85e56 100644 +--- a/fs/nfs/nfs4filelayout.c ++++ b/fs/nfs/nfs4filelayout.c +@@ -122,7 +122,6 @@ static int filelayout_async_handle_error(struct rpc_task *task, + break; + case -NFS4ERR_DELAY: + case -NFS4ERR_GRACE: +- case -EKEYEXPIRED: + rpc_delay(task, FILELAYOUT_POLL_RETRY_MAX); + break; + case -NFS4ERR_RETRY_UNCACHED_REP: +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index d121c67f87d0..cabddb5da071 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -319,7 +319,6 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc + } + case -NFS4ERR_GRACE: + case -NFS4ERR_DELAY: +- case -EKEYEXPIRED: + ret = nfs4_delay(server->client, &exception->timeout); + if (ret != 0) + break; +@@ -1352,13 +1351,6 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state + nfs_inode_find_state_and_recover(state->inode, + stateid); + nfs4_schedule_stateid_recovery(server, state); +- case -EKEYEXPIRED: +- /* +- * User RPCSEC_GSS context has expired. +- * We cannot recover this stateid now, so +- * skip it and allow recovery thread to +- * proceed. +- */ + case -ENOMEM: + err = 0; + goto out; +@@ -3924,7 +3916,6 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, + case -NFS4ERR_DELAY: + nfs_inc_server_stats(server, NFSIOS_DELAY); + case -NFS4ERR_GRACE: +- case -EKEYEXPIRED: + rpc_delay(task, NFS4_POLL_RETRY_MAX); + task->tk_status = 0; + return -EAGAIN; +@@ -4216,6 +4207,7 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock + status = 0; + } + request->fl_ops->fl_release_private(request); ++ request->fl_ops = NULL; + out: + return status; + } +@@ -4871,15 +4863,6 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl) + nfs4_schedule_stateid_recovery(server, state); + err = 0; + goto out; +- case -EKEYEXPIRED: +- /* +- * User RPCSEC_GSS context has expired. +- * We cannot recover this stateid now, so +- * skip it and allow recovery thread to +- * proceed. +- */ +- err = 0; +- goto out; + case -ENOMEM: + case -NFS4ERR_DENIED: + /* kill_proc(fl->fl_pid, SIGLOST, 1); */ +diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c +index 7f0fcfc1fe9d..e46579471ccc 100644 +--- a/fs/nfs/nfs4state.c ++++ b/fs/nfs/nfs4state.c +@@ -1298,14 +1298,6 @@ restart: + /* Mark the file as being 'closed' */ + state->state = 0; + break; +- case -EKEYEXPIRED: +- /* +- * User RPCSEC_GSS context has expired. +- * We cannot recover this stateid now, so +- * skip it and allow recovery thread to +- * proceed. +- */ +- break; + case -NFS4ERR_ADMIN_REVOKED: + case -NFS4ERR_STALE_STATEID: + case -NFS4ERR_BAD_STATEID: +@@ -1458,14 +1450,6 @@ static void nfs4_state_start_reclaim_nograce(struct nfs_client *clp) + nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_nograce); + } + +-static void nfs4_warn_keyexpired(const char *s) +-{ +- printk_ratelimited(KERN_WARNING "Error: state manager" +- " encountered RPCSEC_GSS session" +- " expired against NFSv4 server %s.\n", +- s); +-} +- + static int nfs4_recovery_handle_error(struct nfs_client *clp, int error) + { + switch (error) { +@@ -1497,10 +1481,6 @@ static int nfs4_recovery_handle_error(struct nfs_client *clp, int error) + set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); + /* Zero session reset errors */ + break; +- case -EKEYEXPIRED: +- /* Nothing we can do */ +- nfs4_warn_keyexpired(clp->cl_hostname); +- break; + default: + return error; + } +@@ -1745,7 +1725,6 @@ static void nfs4_set_lease_expired(struct nfs_client *clp, int status) + break; + + case -EKEYEXPIRED: +- nfs4_warn_keyexpired(clp->cl_hostname); + case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery + * in nfs4_exchange_id */ + default: +diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c +index b63b6f4d14fb..af9947e35fcb 100644 +--- a/fs/nfs/proc.c ++++ b/fs/nfs/proc.c +@@ -47,39 +47,6 @@ + #define NFSDBG_FACILITY NFSDBG_PROC + + /* +- * wrapper to handle the -EKEYEXPIRED error message. This should generally +- * only happen if using krb5 auth and a user's TGT expires. NFSv2 doesn't +- * support the NFSERR_JUKEBOX error code, but we handle this situation in the +- * same way that we handle that error with NFSv3. +- */ +-static int +-nfs_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags) +-{ +- int res; +- do { +- res = rpc_call_sync(clnt, msg, flags); +- if (res != -EKEYEXPIRED) +- break; +- freezable_schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME); +- res = -ERESTARTSYS; +- } while (!fatal_signal_pending(current)); +- return res; +-} +- +-#define rpc_call_sync(clnt, msg, flags) nfs_rpc_wrapper(clnt, msg, flags) +- +-static int +-nfs_async_handle_expired_key(struct rpc_task *task) +-{ +- if (task->tk_status != -EKEYEXPIRED) +- return 0; +- task->tk_status = 0; +- rpc_restart_call(task); +- rpc_delay(task, NFS_JUKEBOX_RETRY_TIME); +- return 1; +-} +- +-/* + * Bare-bones access to getattr: this is for nfs_read_super. + */ + static int +@@ -365,8 +332,6 @@ static void nfs_proc_unlink_rpc_prepare(struct rpc_task *task, struct nfs_unlink + + static int nfs_proc_unlink_done(struct rpc_task *task, struct inode *dir) + { +- if (nfs_async_handle_expired_key(task)) +- return 0; + nfs_mark_for_revalidate(dir); + return 1; + } +@@ -386,8 +351,6 @@ static int + nfs_proc_rename_done(struct rpc_task *task, struct inode *old_dir, + struct inode *new_dir) + { +- if (nfs_async_handle_expired_key(task)) +- return 0; + nfs_mark_for_revalidate(old_dir); + nfs_mark_for_revalidate(new_dir); + return 1; +@@ -641,9 +604,6 @@ nfs_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle, + + static int nfs_read_done(struct rpc_task *task, struct nfs_read_data *data) + { +- if (nfs_async_handle_expired_key(task)) +- return -EAGAIN; +- + nfs_invalidate_atime(data->inode); + if (task->tk_status >= 0) { + nfs_refresh_inode(data->inode, data->res.fattr); +@@ -668,9 +628,6 @@ static void nfs_proc_read_rpc_prepare(struct rpc_task *task, struct nfs_read_dat + + static int nfs_write_done(struct rpc_task *task, struct nfs_write_data *data) + { +- if (nfs_async_handle_expired_key(task)) +- return -EAGAIN; +- + if (task->tk_status >= 0) + nfs_post_op_update_inode_force_wcc(data->inode, data->res.fattr); + return 0; +diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c +index f03160106b95..026a873e3f6c 100644 +--- a/fs/nfsd/vfs.c ++++ b/fs/nfsd/vfs.c +@@ -297,41 +297,12 @@ commit_metadata(struct svc_fh *fhp) + } + + /* +- * Set various file attributes. +- * N.B. After this call fhp needs an fh_put ++ * Go over the attributes and take care of the small differences between ++ * NFS semantics and what Linux expects. + */ +-__be32 +-nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, +- int check_guard, time_t guardtime) ++static void ++nfsd_sanitize_attrs(struct inode *inode, struct iattr *iap) + { +- struct dentry *dentry; +- struct inode *inode; +- int accmode = NFSD_MAY_SATTR; +- umode_t ftype = 0; +- __be32 err; +- int host_err; +- int size_change = 0; +- +- if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE)) +- accmode |= NFSD_MAY_WRITE|NFSD_MAY_OWNER_OVERRIDE; +- if (iap->ia_valid & ATTR_SIZE) +- ftype = S_IFREG; +- +- /* Get inode */ +- err = fh_verify(rqstp, fhp, ftype, accmode); +- if (err) +- goto out; +- +- dentry = fhp->fh_dentry; +- inode = dentry->d_inode; +- +- /* Ignore any mode updates on symlinks */ +- if (S_ISLNK(inode->i_mode)) +- iap->ia_valid &= ~ATTR_MODE; +- +- if (!iap->ia_valid) +- goto out; +- + /* + * NFSv2 does not differentiate between "set-[ac]time-to-now" + * which only requires access, and "set-[ac]time-to-X" which +@@ -341,8 +312,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, + * convert to "set to now" instead of "set to explicit time" + * + * We only call inode_change_ok as the last test as technically +- * it is not an interface that we should be using. It is only +- * valid if the filesystem does not define it's own i_op->setattr. ++ * it is not an interface that we should be using. + */ + #define BOTH_TIME_SET (ATTR_ATIME_SET | ATTR_MTIME_SET) + #define MAX_TOUCH_TIME_ERROR (30*60) +@@ -368,30 +338,6 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, + iap->ia_valid &= ~BOTH_TIME_SET; + } + } +- +- /* +- * The size case is special. +- * It changes the file as well as the attributes. +- */ +- if (iap->ia_valid & ATTR_SIZE) { +- if (iap->ia_size < inode->i_size) { +- err = nfsd_permission(rqstp, fhp->fh_export, dentry, +- NFSD_MAY_TRUNC|NFSD_MAY_OWNER_OVERRIDE); +- if (err) +- goto out; +- } +- +- host_err = get_write_access(inode); +- if (host_err) +- goto out_nfserr; +- +- size_change = 1; +- host_err = locks_verify_truncate(inode, NULL, iap->ia_size); +- if (host_err) { +- put_write_access(inode); +- goto out_nfserr; +- } +- } + + /* sanitize the mode change */ + if (iap->ia_valid & ATTR_MODE) { +@@ -414,32 +360,111 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, + iap->ia_valid |= (ATTR_KILL_SUID | ATTR_KILL_SGID); + } + } ++} + +- /* Change the attributes. */ ++static __be32 ++nfsd_get_write_access(struct svc_rqst *rqstp, struct svc_fh *fhp, ++ struct iattr *iap) ++{ ++ struct inode *inode = fhp->fh_dentry->d_inode; ++ int host_err; + +- iap->ia_valid |= ATTR_CTIME; ++ if (iap->ia_size < inode->i_size) { ++ __be32 err; + +- err = nfserr_notsync; +- if (!check_guard || guardtime == inode->i_ctime.tv_sec) { +- host_err = nfsd_break_lease(inode); +- if (host_err) +- goto out_nfserr; +- fh_lock(fhp); ++ err = nfsd_permission(rqstp, fhp->fh_export, fhp->fh_dentry, ++ NFSD_MAY_TRUNC | NFSD_MAY_OWNER_OVERRIDE); ++ if (err) ++ return err; ++ } + +- host_err = notify_change(dentry, iap); +- err = nfserrno(host_err); +- fh_unlock(fhp); ++ host_err = get_write_access(inode); ++ if (host_err) ++ goto out_nfserrno; ++ ++ host_err = locks_verify_truncate(inode, NULL, iap->ia_size); ++ if (host_err) ++ goto out_put_write_access; ++ return 0; ++ ++out_put_write_access: ++ put_write_access(inode); ++out_nfserrno: ++ return nfserrno(host_err); ++} ++ ++/* ++ * Set various file attributes. After this call fhp needs an fh_put. ++ */ ++__be32 ++nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, ++ int check_guard, time_t guardtime) ++{ ++ struct dentry *dentry; ++ struct inode *inode; ++ int accmode = NFSD_MAY_SATTR; ++ umode_t ftype = 0; ++ __be32 err; ++ int host_err; ++ int size_change = 0; ++ ++ if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE)) ++ accmode |= NFSD_MAY_WRITE|NFSD_MAY_OWNER_OVERRIDE; ++ if (iap->ia_valid & ATTR_SIZE) ++ ftype = S_IFREG; ++ ++ /* Get inode */ ++ err = fh_verify(rqstp, fhp, ftype, accmode); ++ if (err) ++ goto out; ++ ++ dentry = fhp->fh_dentry; ++ inode = dentry->d_inode; ++ ++ /* Ignore any mode updates on symlinks */ ++ if (S_ISLNK(inode->i_mode)) ++ iap->ia_valid &= ~ATTR_MODE; ++ ++ if (!iap->ia_valid) ++ goto out; ++ ++ nfsd_sanitize_attrs(inode, iap); ++ ++ /* ++ * The size case is special, it changes the file in addition to the ++ * attributes. ++ */ ++ if (iap->ia_valid & ATTR_SIZE) { ++ err = nfsd_get_write_access(rqstp, fhp, iap); ++ if (err) ++ goto out; ++ size_change = 1; + } ++ ++ iap->ia_valid |= ATTR_CTIME; ++ ++ if (check_guard && guardtime != inode->i_ctime.tv_sec) { ++ err = nfserr_notsync; ++ goto out_put_write_access; ++ } ++ ++ host_err = nfsd_break_lease(inode); ++ if (host_err) ++ goto out_put_write_access_nfserror; ++ ++ fh_lock(fhp); ++ host_err = notify_change(dentry, iap); ++ fh_unlock(fhp); ++ ++out_put_write_access_nfserror: ++ err = nfserrno(host_err); ++out_put_write_access: + if (size_change) + put_write_access(inode); + if (!err) + commit_metadata(fhp); + out: + return err; +- +-out_nfserr: +- err = nfserrno(host_err); +- goto out; + } + + #if defined(CONFIG_NFSD_V2_ACL) || \ +diff --git a/fs/proc/inode.c b/fs/proc/inode.c +index 205c92280838..6c61f119f608 100644 +--- a/fs/proc/inode.c ++++ b/fs/proc/inode.c +@@ -443,12 +443,10 @@ static const struct file_operations proc_reg_file_ops_no_compat = { + + struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de) + { +- struct inode * inode; ++ struct inode *inode = new_inode_pseudo(sb); + +- inode = iget_locked(sb, de->low_ino); +- if (!inode) +- return NULL; +- if (inode->i_state & I_NEW) { ++ if (inode) { ++ inode->i_ino = de->low_ino; + inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; + PROC_I(inode)->fd = 0; + PROC_I(inode)->pde = de; +@@ -477,9 +475,7 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de) + inode->i_fop = de->proc_fops; + } + } +- unlock_new_inode(inode); +- } else +- pde_put(de); ++ } + return inode; + } + +diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h +index 5bab59b1034e..424b381c96f1 100644 +--- a/include/linux/binfmts.h ++++ b/include/linux/binfmts.h +@@ -113,9 +113,6 @@ extern void setup_new_exec(struct linux_binprm * bprm); + extern void would_dump(struct linux_binprm *, struct file *); + + extern int suid_dumpable; +-#define SUID_DUMP_DISABLE 0 /* No setuid dumping */ +-#define SUID_DUMP_USER 1 /* Dump as user of process */ +-#define SUID_DUMP_ROOT 2 /* Dump as root */ + + /* Stack area protections */ + #define EXSTACK_DEFAULT 0 /* Whatever the arch defaults to */ +diff --git a/include/linux/fs.h b/include/linux/fs.h +index 25c40b9f848a..210c347425e8 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -915,9 +915,11 @@ static inline loff_t i_size_read(const struct inode *inode) + static inline void i_size_write(struct inode *inode, loff_t i_size) + { + #if BITS_PER_LONG==32 && defined(CONFIG_SMP) ++ preempt_disable(); + write_seqcount_begin(&inode->i_size_seqcount); + inode->i_size = i_size; + write_seqcount_end(&inode->i_size_seqcount); ++ preempt_enable(); + #elif BITS_PER_LONG==32 && defined(CONFIG_PREEMPT) + preempt_disable(); + inode->i_size = i_size; +diff --git a/include/linux/sched.h b/include/linux/sched.h +index 3dd0efbb70f2..e132a2d24740 100644 +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -404,6 +404,10 @@ static inline void arch_pick_mmap_layout(struct mm_struct *mm) {} + extern void set_dumpable(struct mm_struct *mm, int value); + extern int get_dumpable(struct mm_struct *mm); + ++#define SUID_DUMP_DISABLE 0 /* No setuid dumping */ ++#define SUID_DUMP_USER 1 /* Dump as user of process */ ++#define SUID_DUMP_ROOT 2 /* Dump as root */ ++ + /* mm flags */ + /* dumpable bits */ + #define MMF_DUMPABLE 0 /* core dump is permitted */ +@@ -2466,27 +2470,18 @@ static inline void threadgroup_change_end(struct task_struct *tsk) + * + * Lock the threadgroup @tsk belongs to. No new task is allowed to enter + * and member tasks aren't allowed to exit (as indicated by PF_EXITING) or +- * perform exec. This is useful for cases where the threadgroup needs to +- * stay stable across blockable operations. ++ * change ->group_leader/pid. This is useful for cases where the threadgroup ++ * needs to stay stable across blockable operations. + * + * fork and exit paths explicitly call threadgroup_change_{begin|end}() for + * synchronization. While held, no new task will be added to threadgroup + * and no existing live task will have its PF_EXITING set. + * +- * During exec, a task goes and puts its thread group through unusual +- * changes. After de-threading, exclusive access is assumed to resources +- * which are usually shared by tasks in the same group - e.g. sighand may +- * be replaced with a new one. Also, the exec'ing task takes over group +- * leader role including its pid. Exclude these changes while locked by +- * grabbing cred_guard_mutex which is used to synchronize exec path. ++ * de_thread() does threadgroup_change_{begin|end}() when a non-leader ++ * sub-thread becomes a new leader. + */ + static inline void threadgroup_lock(struct task_struct *tsk) + { +- /* +- * exec uses exit for de-threading nesting group_rwsem inside +- * cred_guard_mutex. Grab cred_guard_mutex first. +- */ +- mutex_lock(&tsk->signal->cred_guard_mutex); + down_write(&tsk->signal->group_rwsem); + } + +@@ -2499,7 +2494,6 @@ static inline void threadgroup_lock(struct task_struct *tsk) + static inline void threadgroup_unlock(struct task_struct *tsk) + { + up_write(&tsk->signal->group_rwsem); +- mutex_unlock(&tsk->signal->cred_guard_mutex); + } + #else + static inline void threadgroup_change_begin(struct task_struct *tsk) {} +diff --git a/kernel/ptrace.c b/kernel/ptrace.c +index daf4394d1aba..a1432369be50 100644 +--- a/kernel/ptrace.c ++++ b/kernel/ptrace.c +@@ -254,7 +254,8 @@ ok: + smp_rmb(); + if (task->mm) + dumpable = get_dumpable(task->mm); +- if (!dumpable && !ptrace_has_cap(task_user_ns(task), mode)) ++ if (dumpable != SUID_DUMP_USER && ++ !ptrace_has_cap(task_user_ns(task), mode)) + return -EPERM; + + return security_ptrace_access_check(task, mode); +diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c +index fee3752ae8f6..d01adb77449c 100644 +--- a/kernel/trace/trace_event_perf.c ++++ b/kernel/trace/trace_event_perf.c +@@ -26,7 +26,7 @@ static int perf_trace_event_perm(struct ftrace_event_call *tp_event, + { + /* The ftrace function trace is allowed only for root. */ + if (ftrace_event_is_function(tp_event) && +- perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN)) ++ perf_paranoid_tracepoint_raw() && !capable(CAP_SYS_ADMIN)) + return -EPERM; + + /* No tracing, just counting, so no obvious leak */ +diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c +index a28a2111297e..f21486a2ac48 100644 +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -1338,6 +1338,7 @@ call_refreshresult(struct rpc_task *task) + rpc_delay(task, 3*HZ); + case -EAGAIN: + status = -EACCES; ++ case -EKEYEXPIRED: + if (!task->tk_cred_retry) + break; + task->tk_cred_retry--; +diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c +index 79064471cd01..31f981d700a3 100644 +--- a/net/sunrpc/xprtsock.c ++++ b/net/sunrpc/xprtsock.c +@@ -390,8 +390,10 @@ static int xs_send_kvec(struct socket *sock, struct sockaddr *addr, int addrlen, + return kernel_sendmsg(sock, &msg, NULL, 0, 0); + } + +-static int xs_send_pagedata(struct socket *sock, struct xdr_buf *xdr, unsigned int base, int more) ++static int xs_send_pagedata(struct socket *sock, struct xdr_buf *xdr, unsigned int base, int more, bool zerocopy) + { ++ ssize_t (*do_sendpage)(struct socket *sock, struct page *page, ++ int offset, size_t size, int flags); + struct page **ppage; + unsigned int remainder; + int err, sent = 0; +@@ -400,6 +402,9 @@ static int xs_send_pagedata(struct socket *sock, struct xdr_buf *xdr, unsigned i + base += xdr->page_base; + ppage = xdr->pages + (base >> PAGE_SHIFT); + base &= ~PAGE_MASK; ++ do_sendpage = sock->ops->sendpage; ++ if (!zerocopy) ++ do_sendpage = sock_no_sendpage; + for(;;) { + unsigned int len = min_t(unsigned int, PAGE_SIZE - base, remainder); + int flags = XS_SENDMSG_FLAGS; +@@ -407,7 +412,7 @@ static int xs_send_pagedata(struct socket *sock, struct xdr_buf *xdr, unsigned i + remainder -= len; + if (remainder != 0 || more) + flags |= MSG_MORE; +- err = sock->ops->sendpage(sock, *ppage, base, len, flags); ++ err = do_sendpage(sock, *ppage, base, len, flags); + if (remainder == 0 || err != len) + break; + sent += err; +@@ -428,9 +433,10 @@ static int xs_send_pagedata(struct socket *sock, struct xdr_buf *xdr, unsigned i + * @addrlen: UDP only -- length of destination address + * @xdr: buffer containing this request + * @base: starting position in the buffer ++ * @zerocopy: true if it is safe to use sendpage() + * + */ +-static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base) ++static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base, bool zerocopy) + { + unsigned int remainder = xdr->len - base; + int err, sent = 0; +@@ -458,7 +464,7 @@ static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, + if (base < xdr->page_len) { + unsigned int len = xdr->page_len - base; + remainder -= len; +- err = xs_send_pagedata(sock, xdr, base, remainder != 0); ++ err = xs_send_pagedata(sock, xdr, base, remainder != 0, zerocopy); + if (remainder == 0 || err != len) + goto out; + sent += err; +@@ -561,7 +567,7 @@ static int xs_local_send_request(struct rpc_task *task) + req->rq_svec->iov_base, req->rq_svec->iov_len); + + status = xs_sendpages(transport->sock, NULL, 0, +- xdr, req->rq_bytes_sent); ++ xdr, req->rq_bytes_sent, true); + dprintk("RPC: %s(%u) = %d\n", + __func__, xdr->len - req->rq_bytes_sent, status); + if (likely(status >= 0)) { +@@ -617,7 +623,7 @@ static int xs_udp_send_request(struct rpc_task *task) + status = xs_sendpages(transport->sock, + xs_addr(xprt), + xprt->addrlen, xdr, +- req->rq_bytes_sent); ++ req->rq_bytes_sent, true); + + dprintk("RPC: xs_udp_send_request(%u) = %d\n", + xdr->len - req->rq_bytes_sent, status); +@@ -688,6 +694,7 @@ static int xs_tcp_send_request(struct rpc_task *task) + struct rpc_xprt *xprt = req->rq_xprt; + struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); + struct xdr_buf *xdr = &req->rq_snd_buf; ++ bool zerocopy = true; + int status; + + xs_encode_stream_record_marker(&req->rq_snd_buf); +@@ -695,13 +702,20 @@ static int xs_tcp_send_request(struct rpc_task *task) + xs_pktdump("packet data:", + req->rq_svec->iov_base, + req->rq_svec->iov_len); ++ /* Don't use zero copy if this is a resend. If the RPC call ++ * completes while the socket holds a reference to the pages, ++ * then we may end up resending corrupted data. ++ */ ++ if (task->tk_flags & RPC_TASK_SENT) ++ zerocopy = false; + + /* Continue transmitting the packet/record. We must be careful + * to cope with writespace callbacks arriving _after_ we have + * called sendmsg(). */ + while (1) { + status = xs_sendpages(transport->sock, +- NULL, 0, xdr, req->rq_bytes_sent); ++ NULL, 0, xdr, req->rq_bytes_sent, ++ zerocopy); + + dprintk("RPC: xs_tcp_send_request(%u) = %d\n", + xdr->len - req->rq_bytes_sent, status); +diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c +index d8edff209bf3..d6aab27c8584 100644 +--- a/security/integrity/ima/ima_policy.c ++++ b/security/integrity/ima/ima_policy.c +@@ -62,7 +62,6 @@ static struct ima_measure_rule_entry default_rules[] = { + {.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC}, + {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC}, + {.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC}, +- {.action = DONT_MEASURE,.fsmagic = RAMFS_MAGIC,.flags = IMA_FSMAGIC}, + {.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC}, + {.action = DONT_MEASURE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC}, + {.action = MEASURE,.func = FILE_MMAP,.mask = MAY_EXEC, +diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c +index 29cc8e162b02..a7d6a52a4f81 100644 +--- a/sound/isa/msnd/msnd_pinnacle.c ++++ b/sound/isa/msnd/msnd_pinnacle.c +@@ -73,9 +73,11 @@ + #ifdef MSND_CLASSIC + # include "msnd_classic.h" + # define LOGNAME "msnd_classic" ++# define DEV_NAME "msnd-classic" + #else + # include "msnd_pinnacle.h" + # define LOGNAME "snd_msnd_pinnacle" ++# define DEV_NAME "msnd-pinnacle" + #endif + + static void __devinit set_default_audio_parameters(struct snd_msnd *chip) +@@ -1068,8 +1070,6 @@ static int __devexit snd_msnd_isa_remove(struct device *pdev, unsigned int dev) + return 0; + } + +-#define DEV_NAME "msnd-pinnacle" +- + static struct isa_driver snd_msnd_driver = { + .match = snd_msnd_isa_match, + .probe = snd_msnd_isa_probe, +diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c +index fc8cc823e438..f8033485db93 100644 +--- a/sound/usb/6fire/chip.c ++++ b/sound/usb/6fire/chip.c +@@ -101,7 +101,7 @@ static int __devinit usb6fire_chip_probe(struct usb_interface *intf, + usb_set_intfdata(intf, chips[i]); + mutex_unlock(®ister_mutex); + return 0; +- } else if (regidx < 0) ++ } else if (!devices[i] && regidx < 0) + regidx = i; + } + if (regidx < 0) { diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.71-72.patch b/patch/kernel/sun8i-default/0001-patch-3.4.71-72.patch new file mode 100644 index 000000000..8498d3d4e --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.71-72.patch @@ -0,0 +1,1614 @@ +diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt +index 6d78841f..99d8ab9d 100644 +--- a/Documentation/sysctl/kernel.txt ++++ b/Documentation/sysctl/kernel.txt +@@ -284,13 +284,24 @@ Default value is "/sbin/hotplug". + kptr_restrict: + + This toggle indicates whether restrictions are placed on +-exposing kernel addresses via /proc and other interfaces. When +-kptr_restrict is set to (0), there are no restrictions. When +-kptr_restrict is set to (1), the default, kernel pointers +-printed using the %pK format specifier will be replaced with 0's +-unless the user has CAP_SYSLOG. When kptr_restrict is set to +-(2), kernel pointers printed using %pK will be replaced with 0's +-regardless of privileges. ++exposing kernel addresses via /proc and other interfaces. ++ ++When kptr_restrict is set to (0), the default, there are no restrictions. ++ ++When kptr_restrict is set to (1), kernel pointers printed using the %pK ++format specifier will be replaced with 0's unless the user has CAP_SYSLOG ++and effective user and group ids are equal to the real ids. This is ++because %pK checks are done at read() time rather than open() time, so ++if permissions are elevated between the open() and the read() (e.g via ++a setuid binary) then %pK will not leak kernel pointers to unprivileged ++users. Note, this is a temporary solution only. The correct long-term ++solution is to do the permission checks at open() time. Consider removing ++world read permissions from files that use %pK, and using dmesg_restrict ++to protect against uses of %pK in dmesg(8) if leaking kernel pointer ++values to unprivileged users is a concern. ++ ++When kptr_restrict is set to (2), kernel pointers printed using ++%pK will be replaced with 0's regardless of privileges. + + ============================================================== + +diff --git a/Makefile b/Makefile +index 05ace570..242e6dfb 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 71 ++SUBLEVEL = 72 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c +index 48a115a9..ecc33bc4 100644 +--- a/arch/arm/mach-integrator/integrator_cp.c ++++ b/arch/arm/mach-integrator/integrator_cp.c +@@ -366,7 +366,8 @@ static AMBA_APB_DEVICE(aaci, "mb:1d", 0, INTEGRATOR_CP_AACI_BASE, + static void cp_clcd_enable(struct clcd_fb *fb) + { + struct fb_var_screeninfo *var = &fb->fb.var; +- u32 val = CM_CTRL_STATIC1 | CM_CTRL_STATIC2; ++ u32 val = CM_CTRL_STATIC1 | CM_CTRL_STATIC2 ++ | CM_CTRL_LCDEN0 | CM_CTRL_LCDEN1; + + if (var->bits_per_pixel <= 8 || + (var->bits_per_pixel == 16 && var->green.length == 5)) +diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c +index 375d3f77..82636701 100644 +--- a/arch/arm/mach-sa1100/assabet.c ++++ b/arch/arm/mach-sa1100/assabet.c +@@ -509,6 +509,9 @@ static void __init assabet_map_io(void) + * Its called GPCLKR0 in my SA1110 manual. + */ + Ser1SDCR0 |= SDCR0_SUS; ++ MSC1 = (MSC1 & ~0xffff) | ++ MSC_NonBrst | MSC_32BitStMem | ++ MSC_RdAcc(2) | MSC_WrAcc(2) | MSC_Rec(0); + + if (!machine_has_neponset()) + sa1100_register_uart_fns(&assabet_port_fns); +diff --git a/arch/avr32/boot/u-boot/head.S b/arch/avr32/boot/u-boot/head.S +index 4488fa27..2ffc298f 100644 +--- a/arch/avr32/boot/u-boot/head.S ++++ b/arch/avr32/boot/u-boot/head.S +@@ -8,6 +8,8 @@ + * published by the Free Software Foundation. + */ + #include ++#include ++#include + + /* + * The kernel is loaded where we want it to be and all caches +@@ -20,11 +22,6 @@ + .section .init.text,"ax" + .global _start + _start: +- /* Check if the boot loader actually provided a tag table */ +- lddpc r0, magic_number +- cp.w r12, r0 +- brne no_tag_table +- + /* Initialize .bss */ + lddpc r2, bss_start_addr + lddpc r3, end_addr +@@ -34,6 +31,25 @@ _start: + cp r2, r3 + brlo 1b + ++ /* Initialize status register */ ++ lddpc r0, init_sr ++ mtsr SYSREG_SR, r0 ++ ++ /* Set initial stack pointer */ ++ lddpc sp, stack_addr ++ sub sp, -THREAD_SIZE ++ ++#ifdef CONFIG_FRAME_POINTER ++ /* Mark last stack frame */ ++ mov lr, 0 ++ mov r7, 0 ++#endif ++ ++ /* Check if the boot loader actually provided a tag table */ ++ lddpc r0, magic_number ++ cp.w r12, r0 ++ brne no_tag_table ++ + /* + * Save the tag table address for later use. This must be done + * _after_ .bss has been initialized... +@@ -53,8 +69,15 @@ bss_start_addr: + .long __bss_start + end_addr: + .long _end ++init_sr: ++ .long 0x007f0000 /* Supervisor mode, everything masked */ ++stack_addr: ++ .long init_thread_union ++panic_addr: ++ .long panic + + no_tag_table: + sub r12, pc, (. - 2f) +- bral panic ++ /* branch to panic() which can be far away with that construct */ ++ lddpc pc, panic_addr + 2: .asciz "Boot loader didn't provide correct magic number\n" +diff --git a/arch/avr32/kernel/entry-avr32b.S b/arch/avr32/kernel/entry-avr32b.S +index 169268c4..a91e8980 100644 +--- a/arch/avr32/kernel/entry-avr32b.S ++++ b/arch/avr32/kernel/entry-avr32b.S +@@ -399,9 +399,10 @@ handle_critical: + /* We should never get here... */ + bad_return: + sub r12, pc, (. - 1f) +- bral panic ++ lddpc pc, 2f + .align 2 + 1: .asciz "Return from critical exception!" ++2: .long panic + + .align 1 + do_bus_error_write: +diff --git a/arch/avr32/kernel/head.S b/arch/avr32/kernel/head.S +index 6163bd0a..59eae6df 100644 +--- a/arch/avr32/kernel/head.S ++++ b/arch/avr32/kernel/head.S +@@ -10,33 +10,13 @@ + #include + + #include +-#include +-#include + + .section .init.text,"ax" + .global kernel_entry + kernel_entry: +- /* Initialize status register */ +- lddpc r0, init_sr +- mtsr SYSREG_SR, r0 +- +- /* Set initial stack pointer */ +- lddpc sp, stack_addr +- sub sp, -THREAD_SIZE +- +-#ifdef CONFIG_FRAME_POINTER +- /* Mark last stack frame */ +- mov lr, 0 +- mov r7, 0 +-#endif +- + /* Start the show */ + lddpc pc, kernel_start_addr + + .align 2 +-init_sr: +- .long 0x007f0000 /* Supervisor mode, everything masked */ +-stack_addr: +- .long init_thread_union + kernel_start_addr: + .long start_kernel +diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c +index e6de7879..32e2c811 100644 +--- a/arch/powerpc/kernel/signal_32.c ++++ b/arch/powerpc/kernel/signal_32.c +@@ -447,6 +447,12 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, + #endif /* CONFIG_ALTIVEC */ + if (copy_fpr_to_user(&frame->mc_fregs, current)) + return 1; ++ ++ /* ++ * Clear the MSR VSX bit to indicate there is no valid state attached ++ * to this context, except in the specific case below where we set it. ++ */ ++ msr &= ~MSR_VSX; + #ifdef CONFIG_VSX + /* + * Copy VSR 0-31 upper half from thread_struct to local +@@ -459,15 +465,7 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, + if (copy_vsx_to_user(&frame->mc_vsregs, current)) + return 1; + msr |= MSR_VSX; +- } else if (!ctx_has_vsx_region) +- /* +- * With a small context structure we can't hold the VSX +- * registers, hence clear the MSR value to indicate the state +- * was not saved. +- */ +- msr &= ~MSR_VSX; +- +- ++ } + #endif /* CONFIG_VSX */ + #ifdef CONFIG_SPE + /* save spe registers */ +diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c +index 2692efdb..3ad1b508 100644 +--- a/arch/powerpc/kernel/signal_64.c ++++ b/arch/powerpc/kernel/signal_64.c +@@ -117,6 +117,12 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, + flush_fp_to_thread(current); + /* copy fpr regs and fpscr */ + err |= copy_fpr_to_user(&sc->fp_regs, current); ++ ++ /* ++ * Clear the MSR VSX bit to indicate there is no valid state attached ++ * to this context, except in the specific case below where we set it. ++ */ ++ msr &= ~MSR_VSX; + #ifdef CONFIG_VSX + /* + * Copy VSX low doubleword to local buffer for formatting, +diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c +index aeb82200..60662545 100644 +--- a/drivers/ata/ahci.c ++++ b/drivers/ata/ahci.c +@@ -402,6 +402,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { + .driver_data = board_ahci_yes_fbs }, /* 88se9172 on some Gigabyte */ + { PCI_DEVICE(0x1b4b, 0x91a3), + .driver_data = board_ahci_yes_fbs }, ++ { PCI_DEVICE(0x1b4b, 0x9230), ++ .driver_data = board_ahci_yes_fbs }, + + /* Promise */ + { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ +diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c +index 47a1fb85..60f41cd2 100644 +--- a/drivers/ata/libahci.c ++++ b/drivers/ata/libahci.c +@@ -1249,9 +1249,11 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class, + { + struct ata_port *ap = link->ap; + struct ahci_host_priv *hpriv = ap->host->private_data; ++ struct ahci_port_priv *pp = ap->private_data; + const char *reason = NULL; + unsigned long now, msecs; + struct ata_taskfile tf; ++ bool fbs_disabled = false; + int rc; + + DPRINTK("ENTER\n"); +@@ -1261,6 +1263,16 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class, + if (rc && rc != -EOPNOTSUPP) + ata_link_warn(link, "failed to reset engine (errno=%d)\n", rc); + ++ /* ++ * According to AHCI-1.2 9.3.9: if FBS is enable, software shall ++ * clear PxFBS.EN to '0' prior to issuing software reset to devices ++ * that is attached to port multiplier. ++ */ ++ if (!ata_is_host_link(link) && pp->fbs_enabled) { ++ ahci_disable_fbs(ap); ++ fbs_disabled = true; ++ } ++ + ata_tf_init(link->device, &tf); + + /* issue the first D2H Register FIS */ +@@ -1301,6 +1313,10 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class, + } else + *class = ahci_dev_classify(ap); + ++ /* re-enable FBS if disabled before */ ++ if (fbs_disabled) ++ ahci_enable_fbs(ap); ++ + DPRINTK("EXIT, class=%u\n", *class); + return 0; + +diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c +index 9cf09ae8..cd20cf1e 100644 +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -4074,6 +4074,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { + { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 }, + { "QUANTUM DAT DAT72-000", NULL, ATA_HORKAGE_ATAPI_MOD16_DMA }, + { "Slimtype DVD A DS8A8SH", NULL, ATA_HORKAGE_MAX_SEC_LBA48 }, ++ { "Slimtype DVD A DS8A9SH", NULL, ATA_HORKAGE_MAX_SEC_LBA48 }, + + /* Devices we expect to fail diagnostics */ + +diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c +index c3419048..92156774 100644 +--- a/drivers/ata/libata-transport.c ++++ b/drivers/ata/libata-transport.c +@@ -319,25 +319,25 @@ int ata_tport_add(struct device *parent, + /* + * ATA link attributes + */ ++static int noop(int x) { return x; } + +- +-#define ata_link_show_linkspeed(field) \ ++#define ata_link_show_linkspeed(field, format) \ + static ssize_t \ + show_ata_link_##field(struct device *dev, \ + struct device_attribute *attr, char *buf) \ + { \ + struct ata_link *link = transport_class_to_link(dev); \ + \ +- return sprintf(buf,"%s\n", sata_spd_string(fls(link->field))); \ ++ return sprintf(buf, "%s\n", sata_spd_string(format(link->field))); \ + } + +-#define ata_link_linkspeed_attr(field) \ +- ata_link_show_linkspeed(field) \ ++#define ata_link_linkspeed_attr(field, format) \ ++ ata_link_show_linkspeed(field, format) \ + static DEVICE_ATTR(field, S_IRUGO, show_ata_link_##field, NULL) + +-ata_link_linkspeed_attr(hw_sata_spd_limit); +-ata_link_linkspeed_attr(sata_spd_limit); +-ata_link_linkspeed_attr(sata_spd); ++ata_link_linkspeed_attr(hw_sata_spd_limit, fls); ++ata_link_linkspeed_attr(sata_spd_limit, fls); ++ata_link_linkspeed_attr(sata_spd, noop); + + + static DECLARE_TRANSPORT_CLASS(ata_link_class, +diff --git a/drivers/block/loop.c b/drivers/block/loop.c +index a4ddbae2..462fd182 100644 +--- a/drivers/block/loop.c ++++ b/drivers/block/loop.c +@@ -1636,7 +1636,7 @@ static int loop_add(struct loop_device **l, int i) + + lo->lo_queue = blk_alloc_queue(GFP_KERNEL); + if (!lo->lo_queue) +- goto out_free_dev; ++ goto out_free_idr; + + disk = lo->lo_disk = alloc_disk(1 << part_shift); + if (!disk) +@@ -1680,6 +1680,8 @@ static int loop_add(struct loop_device **l, int i) + + out_free_queue: + blk_cleanup_queue(lo->lo_queue); ++out_free_idr: ++ idr_remove(&loop_index_idr, i); + out_free_dev: + kfree(lo); + out: +diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c +index 4ed7bf9b..0ed5df4d 100644 +--- a/drivers/block/xen-blkback/blkback.c ++++ b/drivers/block/xen-blkback/blkback.c +@@ -401,6 +401,8 @@ static int dispatch_discard_io(struct xen_blkif *blkif, + unsigned long secure; + struct phys_req preq; + ++ xen_blkif_get(blkif); ++ + preq.sector_number = req->u.discard.sector_number; + preq.nr_sects = req->u.discard.nr_sectors; + +@@ -413,7 +415,6 @@ static int dispatch_discard_io(struct xen_blkif *blkif, + } + blkif->st_ds_req++; + +- xen_blkif_get(blkif); + secure = (blkif->vbd.discard_secure && + (req->u.discard.flag & BLKIF_DISCARD_SECURE)) ? + BLKDEV_DISCARD_SECURE : 0; +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 0e359225..5647ce4b 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -6377,7 +6377,9 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) + intel_crtc->cursor_visible = visible; + } + /* and commit changes on next vblank */ ++ POSTING_READ(CURCNTR(pipe)); + I915_WRITE(CURBASE(pipe), base); ++ POSTING_READ(CURBASE(pipe)); + } + + static void ivb_update_cursor(struct drm_crtc *crtc, u32 base) +@@ -6402,7 +6404,9 @@ static void ivb_update_cursor(struct drm_crtc *crtc, u32 base) + intel_crtc->cursor_visible = visible; + } + /* and commit changes on next vblank */ ++ POSTING_READ(CURCNTR_IVB(pipe)); + I915_WRITE(CURBASE_IVB(pipe), base); ++ POSTING_READ(CURBASE_IVB(pipe)); + } + + /* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */ +diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c +index ed52a6f4..2f46bbfb 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_gem.c ++++ b/drivers/gpu/drm/nouveau/nouveau_gem.c +@@ -281,7 +281,8 @@ validate_fini_list(struct list_head *list, struct nouveau_fence *fence) + list_for_each_safe(entry, tmp, list) { + nvbo = list_entry(entry, struct nouveau_bo, entry); + +- nouveau_bo_fence(nvbo, fence); ++ if (likely(fence)) ++ nouveau_bo_fence(nvbo, fence); + + if (unlikely(nvbo->validate_mapped)) { + ttm_bo_kunmap(&nvbo->kmap); +diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +index 9760e5ad..b44bbf50 100644 +--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c ++++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +@@ -416,6 +416,7 @@ int radeon_crtc_do_set_base(struct drm_crtc *crtc, + /* Pin framebuffer & get tilling informations */ + obj = radeon_fb->obj; + rbo = gem_to_radeon_bo(obj); ++retry: + r = radeon_bo_reserve(rbo, false); + if (unlikely(r != 0)) + return r; +@@ -424,6 +425,33 @@ int radeon_crtc_do_set_base(struct drm_crtc *crtc, + &base); + if (unlikely(r != 0)) { + radeon_bo_unreserve(rbo); ++ ++ /* On old GPU like RN50 with little vram pining can fails because ++ * current fb is taking all space needed. So instead of unpining ++ * the old buffer after pining the new one, first unpin old one ++ * and then retry pining new one. ++ * ++ * As only master can set mode only master can pin and it is ++ * unlikely the master client will race with itself especialy ++ * on those old gpu with single crtc. ++ * ++ * We don't shutdown the display controller because new buffer ++ * will end up in same spot. ++ */ ++ if (!atomic && fb && fb != crtc->fb) { ++ struct radeon_bo *old_rbo; ++ unsigned long nsize, osize; ++ ++ old_rbo = gem_to_radeon_bo(to_radeon_framebuffer(fb)->obj); ++ osize = radeon_bo_size(old_rbo); ++ nsize = radeon_bo_size(rbo); ++ if (nsize <= osize && !radeon_bo_reserve(old_rbo, false)) { ++ radeon_bo_unpin(old_rbo); ++ radeon_bo_unreserve(old_rbo); ++ fb = NULL; ++ goto retry; ++ } ++ } + return -EINVAL; + } + radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); +diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h +index 1767ae7f..a9fcbe44 100644 +--- a/drivers/gpu/drm/radeon/sid.h ++++ b/drivers/gpu/drm/radeon/sid.h +@@ -165,7 +165,7 @@ + #define NOOFGROUPS_SHIFT 12 + #define NOOFGROUPS_MASK 0x00001000 + +-#define MC_SEQ_TRAIN_WAKEUP_CNTL 0x2808 ++#define MC_SEQ_TRAIN_WAKEUP_CNTL 0x28e8 + #define TRAIN_DONE_D0 (1 << 30) + #define TRAIN_DONE_D1 (1 << 31) + +diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c +index f8187ead..2d692626 100644 +--- a/drivers/gpu/drm/ttm/ttm_bo_util.c ++++ b/drivers/gpu/drm/ttm/ttm_bo_util.c +@@ -342,7 +342,9 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, + if (old_iomap == NULL && ttm == NULL) + goto out2; + +- if (ttm->state == tt_unpopulated) { ++ /* TTM might be null for moves within the same region. ++ */ ++ if (ttm && ttm->state == tt_unpopulated) { + ret = ttm->bdev->driver->ttm_tt_populate(ttm); + if (ret) + goto out1; +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index 899c7120..9421f643 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -48,6 +48,12 @@ module_param(iso_layout, uint, 0644); + MODULE_PARM_DESC(iso_layout, "Enable/Disable hardcoded ISO-layout of the keyboard. " + "(0 = disabled, [1] = enabled)"); + ++static unsigned int swap_opt_cmd = 0; ++module_param(swap_opt_cmd, uint, 0644); ++MODULE_PARM_DESC(swap_opt_cmd, "Swap the Option (\"Alt\") and Command (\"Flag\") keys. " ++ "(For people who want to keep Windows PC keyboard muscle memory. " ++ "[0] = as-is, Mac layout. 1 = swapped, Windows layout.)"); ++ + struct apple_sc { + unsigned long quirks; + unsigned int fn_on; +@@ -152,6 +158,14 @@ static const struct apple_key_translation apple_iso_keyboard[] = { + { } + }; + ++static const struct apple_key_translation swapped_option_cmd_keys[] = { ++ { KEY_LEFTALT, KEY_LEFTMETA }, ++ { KEY_LEFTMETA, KEY_LEFTALT }, ++ { KEY_RIGHTALT, KEY_RIGHTMETA }, ++ { KEY_RIGHTMETA,KEY_RIGHTALT }, ++ { } ++}; ++ + static const struct apple_key_translation *apple_find_translation( + const struct apple_key_translation *table, u16 from) + { +@@ -244,6 +258,14 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, + } + } + ++ if (swap_opt_cmd) { ++ trans = apple_find_translation(swapped_option_cmd_keys, usage->code); ++ if (trans) { ++ input_event(input, usage->type, trans->to, value); ++ return 1; ++ } ++ } ++ + return 0; + } + +diff --git a/drivers/hid/hid-roccat-kovaplus.c b/drivers/hid/hid-roccat-kovaplus.c +index 112d9341..1973cff8 100644 +--- a/drivers/hid/hid-roccat-kovaplus.c ++++ b/drivers/hid/hid-roccat-kovaplus.c +@@ -623,9 +623,13 @@ static void kovaplus_keep_values_up_to_date(struct kovaplus_device *kovaplus, + break; + case KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_CPI: + kovaplus->actual_cpi = kovaplus_convert_event_cpi(button_report->data1); ++ break; + case KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_SENSITIVITY: + kovaplus->actual_x_sensitivity = button_report->data1; + kovaplus->actual_y_sensitivity = button_report->data2; ++ break; ++ default: ++ break; + } + } + +diff --git a/drivers/infiniband/hw/ipath/ipath_user_sdma.c b/drivers/infiniband/hw/ipath/ipath_user_sdma.c +index f5cb13b2..cc04b7ba 100644 +--- a/drivers/infiniband/hw/ipath/ipath_user_sdma.c ++++ b/drivers/infiniband/hw/ipath/ipath_user_sdma.c +@@ -280,9 +280,7 @@ static int ipath_user_sdma_pin_pages(const struct ipath_devdata *dd, + int j; + int ret; + +- ret = get_user_pages(current, current->mm, addr, +- npages, 0, 1, pages, NULL); +- ++ ret = get_user_pages_fast(addr, npages, 0, pages); + if (ret != npages) { + int i; + +@@ -811,10 +809,7 @@ int ipath_user_sdma_writev(struct ipath_devdata *dd, + while (dim) { + const int mxp = 8; + +- down_write(¤t->mm->mmap_sem); + ret = ipath_user_sdma_queue_pkts(dd, pq, &list, iov, dim, mxp); +- up_write(¤t->mm->mmap_sem); +- + if (ret <= 0) + goto done_unlock; + else { +diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h +index 5f306f79..0ec9abbe 100644 +--- a/drivers/input/serio/i8042-x86ia64io.h ++++ b/drivers/input/serio/i8042-x86ia64io.h +@@ -765,6 +765,7 @@ static struct pnp_device_id pnp_kbd_devids[] = { + { .id = "CPQA0D7", .driver_data = 0 }, + { .id = "", }, + }; ++MODULE_DEVICE_TABLE(pnp, pnp_kbd_devids); + + static struct pnp_driver i8042_pnp_kbd_driver = { + .name = "i8042 kbd", +@@ -786,6 +787,7 @@ static struct pnp_device_id pnp_aux_devids[] = { + { .id = "SYN0801", .driver_data = 0 }, + { .id = "", }, + }; ++MODULE_DEVICE_TABLE(pnp, pnp_aux_devids); + + static struct pnp_driver i8042_pnp_aux_driver = { + .name = "i8042 aux", +diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c +index f220a695..d509f236 100644 +--- a/drivers/md/dm-table.c ++++ b/drivers/md/dm-table.c +@@ -581,14 +581,28 @@ static int adjoin(struct dm_table *table, struct dm_target *ti) + + /* + * Used to dynamically allocate the arg array. ++ * ++ * We do first allocation with GFP_NOIO because dm-mpath and dm-thin must ++ * process messages even if some device is suspended. These messages have a ++ * small fixed number of arguments. ++ * ++ * On the other hand, dm-switch needs to process bulk data using messages and ++ * excessive use of GFP_NOIO could cause trouble. + */ + static char **realloc_argv(unsigned *array_size, char **old_argv) + { + char **argv; + unsigned new_size; ++ gfp_t gfp; + +- new_size = *array_size ? *array_size * 2 : 64; +- argv = kmalloc(new_size * sizeof(*argv), GFP_KERNEL); ++ if (*array_size) { ++ new_size = *array_size * 2; ++ gfp = GFP_KERNEL; ++ } else { ++ new_size = 8; ++ gfp = GFP_NOIO; ++ } ++ argv = kmalloc(new_size * sizeof(*argv), gfp); + if (argv) { + memcpy(argv, old_argv, *array_size * sizeof(*argv)); + *array_size = new_size; +diff --git a/drivers/md/md.c b/drivers/md/md.c +index 7b45b5e1..e63ca864 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -3507,6 +3507,7 @@ level_store(struct mddev *mddev, const char *buf, size_t len) + mddev->in_sync = 1; + del_timer_sync(&mddev->safemode_timer); + } ++ blk_set_stacking_limits(&mddev->queue->limits); + pers->run(mddev); + mddev_resume(mddev); + set_bit(MD_CHANGE_DEVS, &mddev->flags); +diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +index 9ec51cec..0f000e60 100644 +--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c ++++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +@@ -227,8 +227,6 @@ static void dma_irq_callback(void *param) + struct gpmi_nand_data *this = param; + struct completion *dma_c = &this->dma_done; + +- complete(dma_c); +- + switch (this->dma_type) { + case DMA_FOR_COMMAND: + dma_unmap_sg(this->dev, &this->cmd_sgl, 1, DMA_TO_DEVICE); +@@ -253,6 +251,8 @@ static void dma_irq_callback(void *param) + default: + pr_err("in wrong DMA operation.\n"); + } ++ ++ complete(dma_c); + } + + int start_dma_without_bch_irq(struct gpmi_nand_data *this, +diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c +index eb9f5fb0..e50a0b48 100644 +--- a/drivers/mtd/nand/nand_base.c ++++ b/drivers/mtd/nand/nand_base.c +@@ -2888,10 +2888,21 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, + sanitize_string(p->model, sizeof(p->model)); + if (!mtd->name) + mtd->name = p->model; ++ + mtd->writesize = le32_to_cpu(p->byte_per_page); +- mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize; ++ ++ /* ++ * pages_per_block and blocks_per_lun may not be a power-of-2 size ++ * (don't ask me who thought of this...). MTD assumes that these ++ * dimensions will be power-of-2, so just truncate the remaining area. ++ */ ++ mtd->erasesize = 1 << (fls(le32_to_cpu(p->pages_per_block)) - 1); ++ mtd->erasesize *= mtd->writesize; ++ + mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page); +- chip->chipsize = le32_to_cpu(p->blocks_per_lun); ++ ++ /* See erasesize comment */ ++ chip->chipsize = 1 << (fls(le32_to_cpu(p->blocks_per_lun)) - 1); + chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count; + *busw = 0; + if (le16_to_cpu(p->features) & 1) +diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c +index e2131ca6..eb4014a2 100644 +--- a/drivers/net/can/flexcan.c ++++ b/drivers/net/can/flexcan.c +@@ -667,7 +667,6 @@ static int flexcan_chip_start(struct net_device *dev) + { + struct flexcan_priv *priv = netdev_priv(dev); + struct flexcan_regs __iomem *regs = priv->base; +- unsigned int i; + int err; + u32 reg_mcr, reg_ctrl; + +@@ -735,17 +734,6 @@ static int flexcan_chip_start(struct net_device *dev) + netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl); + flexcan_write(reg_ctrl, ®s->ctrl); + +- for (i = 0; i < ARRAY_SIZE(regs->cantxfg); i++) { +- flexcan_write(0, ®s->cantxfg[i].can_ctrl); +- flexcan_write(0, ®s->cantxfg[i].can_id); +- flexcan_write(0, ®s->cantxfg[i].data[0]); +- flexcan_write(0, ®s->cantxfg[i].data[1]); +- +- /* put MB into rx queue */ +- flexcan_write(FLEXCAN_MB_CNT_CODE(0x4), +- ®s->cantxfg[i].can_ctrl); +- } +- + /* Abort any pending TX, mark Mailbox as INACTIVE */ + flexcan_write(FLEXCAN_MB_CNT_CODE(0x4), + ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl); +diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c +index 4be8ccc8..daf55ba8 100644 +--- a/drivers/net/wireless/mwifiex/sdio.c ++++ b/drivers/net/wireless/mwifiex/sdio.c +@@ -938,7 +938,10 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter, + struct sk_buff *skb, u32 upld_typ) + { + u8 *cmd_buf; ++ __le16 *curr_ptr = (__le16 *)skb->data; ++ u16 pkt_len = le16_to_cpu(*curr_ptr); + ++ skb_trim(skb, pkt_len); + skb_pull(skb, INTF_HEADER_LEN); + + switch (upld_typ) { +diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c +index 5970ff6f..d498b02f 100644 +--- a/drivers/net/wireless/prism54/islpci_dev.c ++++ b/drivers/net/wireless/prism54/islpci_dev.c +@@ -811,6 +811,10 @@ static const struct net_device_ops islpci_netdev_ops = { + .ndo_validate_addr = eth_validate_addr, + }; + ++static struct device_type wlan_type = { ++ .name = "wlan", ++}; ++ + struct net_device * + islpci_setup(struct pci_dev *pdev) + { +@@ -821,9 +825,8 @@ islpci_setup(struct pci_dev *pdev) + return ndev; + + pci_set_drvdata(pdev, ndev); +-#if defined(SET_NETDEV_DEV) + SET_NETDEV_DEV(ndev, &pdev->dev); +-#endif ++ SET_NETDEV_DEVTYPE(ndev, &wlan_type); + + /* setup the structure members */ + ndev->base_addr = pci_resource_start(pdev, 0); +diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c +index 0ea85f46..131b22b8 100644 +--- a/drivers/net/wireless/rt2x00/rt2400pci.c ++++ b/drivers/net/wireless/rt2x00/rt2400pci.c +@@ -1253,7 +1253,7 @@ static void rt2400pci_fill_rxdone(struct queue_entry *entry, + */ + rxdesc->timestamp = ((u64)rx_high << 32) | rx_low; + rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL) & ~0x08; +- rxdesc->rssi = rt2x00_get_field32(word2, RXD_W3_RSSI) - ++ rxdesc->rssi = rt2x00_get_field32(word3, RXD_W3_RSSI) - + entry->queue->rt2x00dev->rssi_offset; + rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); + +diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +index 025bdc2e..4f7f822b 100644 +--- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c ++++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +@@ -762,7 +762,7 @@ static long _rtl92c_signal_scale_mapping(struct ieee80211_hw *hw, + + static void _rtl92c_query_rxphystatus(struct ieee80211_hw *hw, + struct rtl_stats *pstats, +- struct rx_desc_92c *pdesc, ++ struct rx_desc_92c *p_desc, + struct rx_fwinfo_92c *p_drvinfo, + bool packet_match_bssid, + bool packet_toself, +@@ -777,11 +777,11 @@ static void _rtl92c_query_rxphystatus(struct ieee80211_hw *hw, + u32 rssi, total_rssi = 0; + bool in_powersavemode = false; + bool is_cck_rate; ++ u8 *pdesc = (u8 *)p_desc; + +- is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc); ++ is_cck_rate = RX_HAL_IS_CCK_RATE(p_desc); + pstats->packet_matchbssid = packet_match_bssid; + pstats->packet_toself = packet_toself; +- pstats->is_cck = is_cck_rate; + pstats->packet_beacon = packet_beacon; + pstats->is_cck = is_cck_rate; + pstats->RX_SIGQ[0] = -1; +diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +index 9adb21a1..2fd82970 100644 +--- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c ++++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +@@ -303,10 +303,10 @@ out: + bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw, + struct rtl_stats *stats, + struct ieee80211_rx_status *rx_status, +- u8 *p_desc, struct sk_buff *skb) ++ u8 *pdesc, struct sk_buff *skb) + { + struct rx_fwinfo_92c *p_drvinfo; +- struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc; ++ struct rx_desc_92c *p_desc = (struct rx_desc_92c *)pdesc; + u32 phystatus = GET_RX_DESC_PHY_STATUS(pdesc); + + stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc); +@@ -345,11 +345,11 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw, + if (phystatus) { + p_drvinfo = (struct rx_fwinfo_92c *)(skb->data + + stats->rx_bufshift); +- rtl92c_translate_rx_signal_stuff(hw, skb, stats, pdesc, ++ rtl92c_translate_rx_signal_stuff(hw, skb, stats, p_desc, + p_drvinfo); + } + /*rx_status->qual = stats->signal; */ +- rx_status->signal = stats->rssi + 10; ++ rx_status->signal = stats->recvsignalpower + 10; + /*rx_status->noise = -stats->noise; */ + return true; + } +diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +index a7f6126e..1a2bbc2b 100644 +--- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c ++++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +@@ -529,7 +529,7 @@ bool rtl92de_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, + p_drvinfo); + } + /*rx_status->qual = stats->signal; */ +- rx_status->signal = stats->rssi + 10; ++ rx_status->signal = stats->recvsignalpower + 10; + /*rx_status->noise = -stats->noise; */ + return true; + } +diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c +index 08c2f562..c405f967 100644 +--- a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c ++++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c +@@ -268,7 +268,7 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, + rtlefuse->pwrgroup_ht40 + [RF90_PATH_A][chnl - 1]) { + pwrdiff_limit[i] = +- rtlefuse->pwrgroup_ht20 ++ rtlefuse->pwrgroup_ht40 + [RF90_PATH_A][chnl - 1]; + } + } else { +diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +index 2fd3d13b..94bbce82 100644 +--- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c ++++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +@@ -582,7 +582,7 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, + } + + /*rx_status->qual = stats->signal; */ +- rx_status->signal = stats->rssi + 10; ++ rx_status->signal = stats->recvsignalpower + 10; + /*rx_status->noise = -stats->noise; */ + + return true; +diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c +index e0610bda..7e41b70a 100644 +--- a/drivers/pci/pcie/portdrv_pci.c ++++ b/drivers/pci/pcie/portdrv_pci.c +@@ -151,7 +151,6 @@ static int __devinit pcie_portdrv_probe(struct pci_dev *dev, + static void pcie_portdrv_remove(struct pci_dev *dev) + { + pcie_port_device_remove(dev); +- pci_disable_device(dev); + } + + static int error_detected_iter(struct device *device, void *data) +diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c +index 8334dadc..be56590b 100644 +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -4357,7 +4357,7 @@ int qeth_snmp_command(struct qeth_card *card, char __user *udata) + struct qeth_cmd_buffer *iob; + struct qeth_ipa_cmd *cmd; + struct qeth_snmp_ureq *ureq; +- int req_len; ++ unsigned int req_len; + struct qeth_arp_query_info qinfo = {0, }; + int rc = 0; + +@@ -4373,6 +4373,10 @@ int qeth_snmp_command(struct qeth_card *card, char __user *udata) + /* skip 4 bytes (data_len struct member) to get req_len */ + if (copy_from_user(&req_len, udata + sizeof(int), sizeof(int))) + return -EFAULT; ++ if (req_len > (QETH_BUFSIZE - IPA_PDU_HEADER_SIZE - ++ sizeof(struct qeth_ipacmd_hdr) - ++ sizeof(struct qeth_ipacmd_setadpparms_hdr))) ++ return -EINVAL; + ureq = memdup_user(udata, req_len + sizeof(struct qeth_snmp_ureq_hdr)); + if (IS_ERR(ureq)) { + QETH_CARD_TEXT(card, 2, "snmpnome"); +diff --git a/drivers/staging/media/lirc/lirc_zilog.c b/drivers/staging/media/lirc/lirc_zilog.c +index 76ea4a8f..56a96d32 100644 +--- a/drivers/staging/media/lirc/lirc_zilog.c ++++ b/drivers/staging/media/lirc/lirc_zilog.c +@@ -61,6 +61,9 @@ + #include + #include + ++/* Max transfer size done by I2C transfer functions */ ++#define MAX_XFER_SIZE 64 ++ + struct IR; + + struct IR_rx { +@@ -942,7 +945,14 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos) + schedule(); + set_current_state(TASK_INTERRUPTIBLE); + } else { +- unsigned char buf[rbuf->chunk_size]; ++ unsigned char buf[MAX_XFER_SIZE]; ++ ++ if (rbuf->chunk_size > sizeof(buf)) { ++ zilog_error("chunk_size is too big (%d)!\n", ++ rbuf->chunk_size); ++ ret = -EINVAL; ++ break; ++ } + m = lirc_buffer_read(rbuf, buf); + if (m == rbuf->chunk_size) { + ret = copy_to_user((void *)outbuf+written, buf, +diff --git a/drivers/staging/tidspbridge/Kconfig b/drivers/staging/tidspbridge/Kconfig +index 0dd479f5..f67c78e5 100644 +--- a/drivers/staging/tidspbridge/Kconfig ++++ b/drivers/staging/tidspbridge/Kconfig +@@ -4,7 +4,7 @@ + + menuconfig TIDSPBRIDGE + tristate "DSP Bridge driver" +- depends on ARCH_OMAP3 ++ depends on ARCH_OMAP3 && BROKEN + select OMAP_MBOX_FWK + help + DSP/BIOS Bridge is designed for platforms that contain a GPP and +diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c +index 06f27f62..858e2a8e 100644 +--- a/drivers/staging/vt6656/baseband.c ++++ b/drivers/staging/vt6656/baseband.c +@@ -976,6 +976,7 @@ BOOL BBbVT3184Init(PSDevice pDevice) + PBYTE pbyAgc; + WORD wLengthAgc; + BYTE abyArray[256]; ++ u8 data; + + ntStatus = CONTROLnsRequestIn(pDevice, + MESSAGE_TYPE_READ, +@@ -1144,6 +1145,16 @@ else { + ControlvWriteByte(pDevice,MESSAGE_REQUEST_BBREG,0x0D,0x01); + + RFbRFTableDownload(pDevice); ++ ++ /* Fix for TX USB resets from vendors driver */ ++ CONTROLnsRequestIn(pDevice, MESSAGE_TYPE_READ, USB_REG4, ++ MESSAGE_REQUEST_MEM, sizeof(data), &data); ++ ++ data |= 0x2; ++ ++ CONTROLnsRequestOut(pDevice, MESSAGE_TYPE_WRITE, USB_REG4, ++ MESSAGE_REQUEST_MEM, sizeof(data), &data); ++ + return TRUE;//ntStatus; + } + +diff --git a/drivers/staging/vt6656/rndis.h b/drivers/staging/vt6656/rndis.h +index fccf7e98..dcf7bf54 100644 +--- a/drivers/staging/vt6656/rndis.h ++++ b/drivers/staging/vt6656/rndis.h +@@ -69,6 +69,7 @@ + + #define VIAUSB20_PACKET_HEADER 0x04 + ++#define USB_REG4 0x604 + + /*--------------------- Export Classes ----------------------------*/ + +diff --git a/drivers/target/iscsi/iscsi_target_auth.c b/drivers/target/iscsi/iscsi_target_auth.c +index a0fc7b9e..b54f6ecf 100644 +--- a/drivers/target/iscsi/iscsi_target_auth.c ++++ b/drivers/target/iscsi/iscsi_target_auth.c +@@ -174,6 +174,7 @@ static int chap_server_compute_md5( + unsigned char client_digest[MD5_SIGNATURE_SIZE]; + unsigned char server_digest[MD5_SIGNATURE_SIZE]; + unsigned char chap_n[MAX_CHAP_N_SIZE], chap_r[MAX_RESPONSE_LENGTH]; ++ size_t compare_len; + struct iscsi_chap *chap = conn->auth_protocol; + struct crypto_hash *tfm; + struct hash_desc desc; +@@ -212,7 +213,9 @@ static int chap_server_compute_md5( + goto out; + } + +- if (memcmp(chap_n, auth->userid, strlen(auth->userid)) != 0) { ++ /* Include the terminating NULL in the compare */ ++ compare_len = strlen(auth->userid) + 1; ++ if (strncmp(chap_n, auth->userid, compare_len) != 0) { + pr_err("CHAP_N values do not match!\n"); + goto out; + } +diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c +index 2dba448c..60470ee9 100644 +--- a/drivers/target/iscsi/iscsi_target_nego.c ++++ b/drivers/target/iscsi/iscsi_target_nego.c +@@ -89,7 +89,7 @@ int extract_param( + if (len < 0) + return -1; + +- if (len > max_length) { ++ if (len >= max_length) { + pr_err("Length of input: %d exceeds max_length:" + " %d\n", len, max_length); + return -1; +diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c +index 0443a4f7..4d2bbd89 100644 +--- a/drivers/video/backlight/atmel-pwm-bl.c ++++ b/drivers/video/backlight/atmel-pwm-bl.c +@@ -70,7 +70,7 @@ static int atmel_pwm_bl_set_intensity(struct backlight_device *bd) + static int atmel_pwm_bl_get_intensity(struct backlight_device *bd) + { + struct atmel_pwm_bl *pwmbl = bl_get_data(bd); +- u8 intensity; ++ u32 intensity; + + if (pwmbl->pdata->pwm_active_low) { + intensity = pwm_channel_readl(&pwmbl->pwmc, PWM_CDTY) - +@@ -80,7 +80,7 @@ static int atmel_pwm_bl_get_intensity(struct backlight_device *bd) + pwm_channel_readl(&pwmbl->pwmc, PWM_CDTY); + } + +- return intensity; ++ return intensity & 0xffff; + } + + static int atmel_pwm_bl_init_pwm(struct atmel_pwm_bl *pwmbl) +diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c +index 10f5e0b4..901c3d74 100644 +--- a/fs/devpts/inode.c ++++ b/fs/devpts/inode.c +@@ -475,6 +475,7 @@ static void devpts_kill_sb(struct super_block *sb) + { + struct pts_fs_info *fsi = DEVPTS_SB(sb); + ++ ida_destroy(&fsi->allocated_ptys); + kfree(fsi); + kill_litter_super(sb); + } +diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c +index b1aa7fd4..01f2cf34 100644 +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -1270,6 +1270,7 @@ retry: + new_extra_isize = s_min_extra_isize; + kfree(is); is = NULL; + kfree(bs); bs = NULL; ++ brelse(bh); + goto retry; + } + error = -1; +diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h +index 3595a023..292645fc 100644 +--- a/include/linux/mtd/map.h ++++ b/include/linux/mtd/map.h +@@ -362,7 +362,7 @@ static inline map_word map_word_load_partial(struct map_info *map, map_word orig + bitpos = (map_bankwidth(map)-1-i)*8; + #endif + orig.x[0] &= ~(0xff << bitpos); +- orig.x[0] |= buf[i-start] << bitpos; ++ orig.x[0] |= (unsigned long)buf[i-start] << bitpos; + } + } + return orig; +@@ -381,7 +381,7 @@ static inline map_word map_word_ff(struct map_info *map) + + if (map_bankwidth(map) < MAP_FF_LIMIT) { + int bw = 8 * map_bankwidth(map); +- r.x[0] = (1 << bw) - 1; ++ r.x[0] = (1UL << bw) - 1; + } else { + for (i=0; inlmsg_len < sizeof(struct audit_status)) ++ if (nlmsg_len(nlh) < sizeof(struct audit_status)) + return -EINVAL; + status_get = (struct audit_status *)data; + if (status_get->mask & AUDIT_STATUS_ENABLED) { +diff --git a/kernel/cpuset.c b/kernel/cpuset.c +index 8fe6f6b6..e372d949 100644 +--- a/kernel/cpuset.c ++++ b/kernel/cpuset.c +@@ -983,8 +983,10 @@ static void cpuset_change_task_nodemask(struct task_struct *tsk, + need_loop = task_has_mempolicy(tsk) || + !nodes_intersects(*newmems, tsk->mems_allowed); + +- if (need_loop) ++ if (need_loop) { ++ local_irq_disable(); + write_seqcount_begin(&tsk->mems_allowed_seq); ++ } + + nodes_or(tsk->mems_allowed, tsk->mems_allowed, *newmems); + mpol_rebind_task(tsk, newmems, MPOL_REBIND_STEP1); +@@ -992,8 +994,10 @@ static void cpuset_change_task_nodemask(struct task_struct *tsk, + mpol_rebind_task(tsk, newmems, MPOL_REBIND_STEP2); + tsk->mems_allowed = *newmems; + +- if (need_loop) ++ if (need_loop) { + write_seqcount_end(&tsk->mems_allowed_seq); ++ local_irq_enable(); ++ } + + task_unlock(tsk); + } +diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c +index 0de28576..91c04f16 100644 +--- a/kernel/power/snapshot.c ++++ b/kernel/power/snapshot.c +@@ -1398,7 +1398,11 @@ int hibernate_preallocate_memory(void) + * highmem and non-highmem zones separately. + */ + pages_highmem = preallocate_image_highmem(highmem / 2); +- alloc = (count - max_size) - pages_highmem; ++ alloc = count - max_size; ++ if (alloc > pages_highmem) ++ alloc -= pages_highmem; ++ else ++ alloc = 0; + pages = preallocate_image_memory(alloc, avail_normal); + if (pages < alloc) { + /* We have exhausted non-highmem pages, try highmem. */ +diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c +index 8a538c55..877aa733 100644 +--- a/kernel/time/alarmtimer.c ++++ b/kernel/time/alarmtimer.c +@@ -474,7 +474,7 @@ static int alarm_clock_getres(const clockid_t which_clock, struct timespec *tp) + clockid_t baseid = alarm_bases[clock2alarm(which_clock)].base_clockid; + + if (!alarmtimer_get_rtcdev()) +- return -ENOTSUPP; ++ return -EINVAL; + + return hrtimer_get_res(baseid, tp); + } +@@ -491,7 +491,7 @@ static int alarm_clock_get(clockid_t which_clock, struct timespec *tp) + struct alarm_base *base = &alarm_bases[clock2alarm(which_clock)]; + + if (!alarmtimer_get_rtcdev()) +- return -ENOTSUPP; ++ return -EINVAL; + + *tp = ktime_to_timespec(base->gettime()); + return 0; +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index e101cf9a..8c8169bf 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -312,9 +312,6 @@ static int remove_ftrace_list_ops(struct ftrace_ops **list, + + static int __register_ftrace_function(struct ftrace_ops *ops) + { +- if (ftrace_disabled) +- return -ENODEV; +- + if (FTRACE_WARN_ON(ops == &global_ops)) + return -EINVAL; + +@@ -348,9 +345,6 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops) + { + int ret; + +- if (ftrace_disabled) +- return -ENODEV; +- + if (WARN_ON(!(ops->flags & FTRACE_OPS_FL_ENABLED))) + return -EBUSY; + +@@ -1940,10 +1934,15 @@ static void ftrace_startup_enable(int command) + static int ftrace_startup(struct ftrace_ops *ops, int command) + { + bool hash_enable = true; ++ int ret; + + if (unlikely(ftrace_disabled)) + return -ENODEV; + ++ ret = __register_ftrace_function(ops); ++ if (ret) ++ return ret; ++ + ftrace_start_up++; + command |= FTRACE_UPDATE_CALLS; + +@@ -1965,12 +1964,17 @@ static int ftrace_startup(struct ftrace_ops *ops, int command) + return 0; + } + +-static void ftrace_shutdown(struct ftrace_ops *ops, int command) ++static int ftrace_shutdown(struct ftrace_ops *ops, int command) + { + bool hash_disable = true; ++ int ret; + + if (unlikely(ftrace_disabled)) +- return; ++ return -ENODEV; ++ ++ ret = __unregister_ftrace_function(ops); ++ if (ret) ++ return ret; + + ftrace_start_up--; + /* +@@ -2005,9 +2009,10 @@ static void ftrace_shutdown(struct ftrace_ops *ops, int command) + } + + if (!command || !ftrace_enabled) +- return; ++ return 0; + + ftrace_run_update_code(command); ++ return 0; + } + + static void ftrace_startup_sysctl(void) +@@ -2873,16 +2878,13 @@ static void __enable_ftrace_function_probe(void) + if (i == FTRACE_FUNC_HASHSIZE) + return; + +- ret = __register_ftrace_function(&trace_probe_ops); +- if (!ret) +- ret = ftrace_startup(&trace_probe_ops, 0); ++ ret = ftrace_startup(&trace_probe_ops, 0); + + ftrace_probe_registered = 1; + } + + static void __disable_ftrace_function_probe(void) + { +- int ret; + int i; + + if (!ftrace_probe_registered) +@@ -2895,9 +2897,7 @@ static void __disable_ftrace_function_probe(void) + } + + /* no more funcs left */ +- ret = __unregister_ftrace_function(&trace_probe_ops); +- if (!ret) +- ftrace_shutdown(&trace_probe_ops, 0); ++ ftrace_shutdown(&trace_probe_ops, 0); + + ftrace_probe_registered = 0; + } +@@ -3948,12 +3948,15 @@ device_initcall(ftrace_nodyn_init); + static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; } + static inline void ftrace_startup_enable(int command) { } + /* Keep as macros so we do not need to define the commands */ +-# define ftrace_startup(ops, command) \ +- ({ \ +- (ops)->flags |= FTRACE_OPS_FL_ENABLED; \ +- 0; \ ++# define ftrace_startup(ops, command) \ ++ ({ \ ++ int ___ret = __register_ftrace_function(ops); \ ++ if (!___ret) \ ++ (ops)->flags |= FTRACE_OPS_FL_ENABLED; \ ++ ___ret; \ + }) +-# define ftrace_shutdown(ops, command) do { } while (0) ++# define ftrace_shutdown(ops, command) __unregister_ftrace_function(ops) ++ + # define ftrace_startup_sysctl() do { } while (0) + # define ftrace_shutdown_sysctl() do { } while (0) + +@@ -4323,15 +4326,8 @@ int register_ftrace_function(struct ftrace_ops *ops) + + mutex_lock(&ftrace_lock); + +- if (unlikely(ftrace_disabled)) +- goto out_unlock; +- +- ret = __register_ftrace_function(ops); +- if (!ret) +- ret = ftrace_startup(ops, 0); +- ++ ret = ftrace_startup(ops, 0); + +- out_unlock: + mutex_unlock(&ftrace_lock); + return ret; + } +@@ -4348,9 +4344,7 @@ int unregister_ftrace_function(struct ftrace_ops *ops) + int ret; + + mutex_lock(&ftrace_lock); +- ret = __unregister_ftrace_function(ops); +- if (!ret) +- ftrace_shutdown(ops, 0); ++ ret = ftrace_shutdown(ops, 0); + mutex_unlock(&ftrace_lock); + + return ret; +@@ -4544,6 +4538,12 @@ ftrace_suspend_notifier_call(struct notifier_block *bl, unsigned long state, + return NOTIFY_DONE; + } + ++/* Just a place holder for function graph */ ++static struct ftrace_ops fgraph_ops __read_mostly = { ++ .func = ftrace_stub, ++ .flags = FTRACE_OPS_FL_GLOBAL, ++}; ++ + int register_ftrace_graph(trace_func_graph_ret_t retfunc, + trace_func_graph_ent_t entryfunc) + { +@@ -4570,7 +4570,7 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc, + ftrace_graph_return = retfunc; + ftrace_graph_entry = entryfunc; + +- ret = ftrace_startup(&global_ops, FTRACE_START_FUNC_RET); ++ ret = ftrace_startup(&fgraph_ops, FTRACE_START_FUNC_RET); + + out: + mutex_unlock(&ftrace_lock); +@@ -4587,7 +4587,7 @@ void unregister_ftrace_graph(void) + ftrace_graph_active--; + ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub; + ftrace_graph_entry = ftrace_graph_entry_stub; +- ftrace_shutdown(&global_ops, FTRACE_STOP_FUNC_RET); ++ ftrace_shutdown(&fgraph_ops, FTRACE_STOP_FUNC_RET); + unregister_pm_notifier(&ftrace_suspend_notifier); + unregister_trace_sched_switch(ftrace_graph_probe_sched_switch, NULL); + +diff --git a/lib/vsprintf.c b/lib/vsprintf.c +index abbabec9..73e2c45a 100644 +--- a/lib/vsprintf.c ++++ b/lib/vsprintf.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + + #include /* for PAGE_SIZE */ +@@ -930,11 +931,37 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, + spec.field_width = 2 * sizeof(void *); + return string(buf, end, "pK-error", spec); + } +- if (!((kptr_restrict == 0) || +- (kptr_restrict == 1 && +- has_capability_noaudit(current, CAP_SYSLOG)))) ++ ++ switch (kptr_restrict) { ++ case 0: ++ /* Always print %pK values */ ++ break; ++ case 1: { ++ /* ++ * Only print the real pointer value if the current ++ * process has CAP_SYSLOG and is running with the ++ * same credentials it started with. This is because ++ * access to files is checked at open() time, but %pK ++ * checks permission at read() time. We don't want to ++ * leak pointer values if a binary opens a file using ++ * %pK and then elevates privileges before reading it. ++ */ ++ const struct cred *cred = current_cred(); ++ ++ if (!has_capability_noaudit(current, CAP_SYSLOG) || ++ (cred->euid != cred->uid) || ++ (cred->egid != cred->gid)) ++ ptr = NULL; ++ break; ++ } ++ case 2: ++ default: ++ /* Always print 0's for %pK */ + ptr = NULL; ++ break; ++ } + break; ++ + case 'N': + switch (fmt[1]) { + case 'F': +diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c +index da4b8b23..6235d052 100644 +--- a/security/selinux/netlabel.c ++++ b/security/selinux/netlabel.c +@@ -442,8 +442,7 @@ int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr) + sksec->nlbl_state != NLBL_CONNLABELED) + return 0; + +- local_bh_disable(); +- bh_lock_sock_nested(sk); ++ lock_sock(sk); + + /* connected sockets are allowed to disconnect when the address family + * is set to AF_UNSPEC, if that is what is happening we want to reset +@@ -464,7 +463,6 @@ int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr) + sksec->nlbl_state = NLBL_CONNLABELED; + + socket_connect_return: +- bh_unlock_sock(sk); +- local_bh_enable(); ++ release_sock(sk); + return rc; + } +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 810f1fc2..c32ae4d5 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -6969,6 +6969,7 @@ static int patch_alc662(struct hda_codec *codec) + case 0x10ec0272: + case 0x10ec0663: + case 0x10ec0665: ++ case 0x10ec0668: + set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); + break; + case 0x10ec0273: +diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c +index 4dccf037..f59a961b 100644 +--- a/sound/soc/blackfin/bf5xx-i2s.c ++++ b/sound/soc/blackfin/bf5xx-i2s.c +@@ -111,6 +111,7 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream, + bf5xx_i2s->tcr2 |= 7; + bf5xx_i2s->rcr2 |= 7; + sport_handle->wdsize = 1; ++ break; + case SNDRV_PCM_FORMAT_S16_LE: + bf5xx_i2s->tcr2 |= 15; + bf5xx_i2s->rcr2 |= 15; +diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c +index b3e24f28..7e4245f1 100644 +--- a/sound/soc/codecs/ak4642.c ++++ b/sound/soc/codecs/ak4642.c +@@ -262,7 +262,7 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream, + * This operation came from example code of + * "ASAHI KASEI AK4642" (japanese) manual p94. + */ +- snd_soc_write(codec, SG_SL1, PMMP | MGAIN0); ++ snd_soc_update_bits(codec, SG_SL1, PMMP | MGAIN0, PMMP | MGAIN0); + snd_soc_write(codec, TIMER, ZTM(0x3) | WTM(0x3)); + snd_soc_write(codec, ALC_CTL1, ALC | LMTH0); + snd_soc_update_bits(codec, PW_MGMT1, PMADL, PMADL); +diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c +index e96c6ede..0b5132f7 100644 +--- a/sound/soc/codecs/wm8962.c ++++ b/sound/soc/codecs/wm8962.c +@@ -3675,6 +3675,8 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, + if (ret < 0) + goto err_regmap; + ++ regcache_cache_only(wm8962->regmap, true); ++ + /* The drivers should power up as needed */ + regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); + +diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c +index bdfbc1be..91a0a2f8 100644 +--- a/virt/kvm/kvm_main.c ++++ b/virt/kvm/kvm_main.c +@@ -774,7 +774,7 @@ int __kvm_set_memory_region(struct kvm *kvm, + /* destroy any largepage mappings for dirty tracking */ + } + +- if (!npages) { ++ if (!npages || base_gfn != old.base_gfn) { + struct kvm_memory_slot *slot; + + r = -ENOMEM; +@@ -790,8 +790,10 @@ int __kvm_set_memory_region(struct kvm *kvm, + old_memslots = kvm->memslots; + rcu_assign_pointer(kvm->memslots, slots); + synchronize_srcu_expedited(&kvm->srcu); +- /* From this point no new shadow pages pointing to a deleted +- * memslot will be created. ++ /* slot was deleted or moved, clear iommu mapping */ ++ kvm_iommu_unmap_pages(kvm, &old); ++ /* From this point no new shadow pages pointing to a deleted, ++ * or moved, memslot will be created. + * + * validation of sp->gfn happens in: + * - gfn_to_hva (kvm_read_guest, gfn_to_pfn) +@@ -805,20 +807,19 @@ int __kvm_set_memory_region(struct kvm *kvm, + if (r) + goto out_free; + +- /* map/unmap the pages in iommu page table */ +- if (npages) { +- r = kvm_iommu_map_pages(kvm, &new); +- if (r) +- goto out_free; +- } else +- kvm_iommu_unmap_pages(kvm, &old); +- + r = -ENOMEM; + slots = kmemdup(kvm->memslots, sizeof(struct kvm_memslots), + GFP_KERNEL); + if (!slots) + goto out_free; + ++ /* map new memory slot into the iommu */ ++ if (npages) { ++ r = kvm_iommu_map_pages(kvm, &new); ++ if (r) ++ goto out_slots; ++ } ++ + /* actual memory is freed via old in kvm_free_physmem_slot below */ + if (!npages) { + new.rmap = NULL; +@@ -845,6 +846,8 @@ int __kvm_set_memory_region(struct kvm *kvm, + + return 0; + ++out_slots: ++ kfree(slots); + out_free: + kvm_free_physmem_slot(&new, &old); + out: diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.72-73.patch b/patch/kernel/sun8i-default/0001-patch-3.4.72-73.patch new file mode 100644 index 000000000..a480e470c --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.72-73.patch @@ -0,0 +1,2401 @@ +diff --git a/Makefile b/Makefile +index 242e6dfbff19..2ea579016292 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 72 ++SUBLEVEL = 73 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/block/blk-core.c b/block/blk-core.c +index a02cfb7e4123..279f05dcbc87 100644 +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -499,7 +499,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id) + goto fail_id; + + if (blk_throtl_init(q)) +- goto fail_id; ++ goto fail_bdi; + + setup_timer(&q->backing_dev_info.laptop_mode_wb_timer, + laptop_mode_timer_fn, (unsigned long) q); +@@ -524,6 +524,8 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id) + + return q; + ++fail_bdi: ++ bdi_destroy(&q->backing_dev_info); + fail_id: + ida_simple_remove(&blk_queue_ida, q->id); + fail_q: +diff --git a/block/elevator.c b/block/elevator.c +index f016855a46b0..dcef5d1bf999 100644 +--- a/block/elevator.c ++++ b/block/elevator.c +@@ -961,7 +961,7 @@ fail_register: + /* + * Switch this queue to the given IO scheduler. + */ +-int elevator_change(struct request_queue *q, const char *name) ++static int __elevator_change(struct request_queue *q, const char *name) + { + char elevator_name[ELV_NAME_MAX]; + struct elevator_type *e; +@@ -983,6 +983,18 @@ int elevator_change(struct request_queue *q, const char *name) + + return elevator_switch(q, e); + } ++ ++int elevator_change(struct request_queue *q, const char *name) ++{ ++ int ret; ++ ++ /* Protect q->elevator from elevator_init() */ ++ mutex_lock(&q->sysfs_lock); ++ ret = __elevator_change(q, name); ++ mutex_unlock(&q->sysfs_lock); ++ ++ return ret; ++} + EXPORT_SYMBOL(elevator_change); + + ssize_t elv_iosched_store(struct request_queue *q, const char *name, +@@ -993,7 +1005,7 @@ ssize_t elv_iosched_store(struct request_queue *q, const char *name, + if (!q->elevator) + return count; + +- ret = elevator_change(q, name); ++ ret = __elevator_change(q, name); + if (!ret) + return count; + +diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c +index 0262210cad38..850246206b12 100644 +--- a/crypto/algif_hash.c ++++ b/crypto/algif_hash.c +@@ -114,6 +114,9 @@ static ssize_t hash_sendpage(struct socket *sock, struct page *page, + struct hash_ctx *ctx = ask->private; + int err; + ++ if (flags & MSG_SENDPAGE_NOTLAST) ++ flags |= MSG_MORE; ++ + lock_sock(sk); + sg_init_table(ctx->sgl.sg, 1); + sg_set_page(ctx->sgl.sg, page, size, offset); +@@ -161,8 +164,6 @@ static int hash_recvmsg(struct kiocb *unused, struct socket *sock, + else if (len < ds) + msg->msg_flags |= MSG_TRUNC; + +- msg->msg_namelen = 0; +- + lock_sock(sk); + if (ctx->more) { + ctx->more = 0; +diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c +index a1c4f0a55583..a19c027b29bd 100644 +--- a/crypto/algif_skcipher.c ++++ b/crypto/algif_skcipher.c +@@ -378,6 +378,9 @@ static ssize_t skcipher_sendpage(struct socket *sock, struct page *page, + struct skcipher_sg_list *sgl; + int err = -EINVAL; + ++ if (flags & MSG_SENDPAGE_NOTLAST) ++ flags |= MSG_MORE; ++ + lock_sock(sk); + if (!ctx->more && ctx->used) + goto unlock; +@@ -432,7 +435,6 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock, + long copied = 0; + + lock_sock(sk); +- msg->msg_namelen = 0; + for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0; + iovlen--, iov++) { + unsigned long seglen = iov->iov_len; +diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c +index 1c052127548c..b0e75ce3c8fc 100644 +--- a/drivers/atm/idt77252.c ++++ b/drivers/atm/idt77252.c +@@ -3513,7 +3513,7 @@ init_card(struct atm_dev *dev) + tmp = dev_get_by_name(&init_net, tname); /* jhs: was "tmp = dev_get(tname);" */ + if (tmp) { + memcpy(card->atmdev->esi, tmp->dev_addr, 6); +- ++ dev_put(tmp); + printk("%s: ESI %pM\n", card->name, card->atmdev->esi); + } + /* +diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c +index 2894461e0bdb..ff18e41f5b22 100644 +--- a/drivers/connector/cn_proc.c ++++ b/drivers/connector/cn_proc.c +@@ -31,11 +31,23 @@ + #include + #include + +-#include +- + #include + +-#define CN_PROC_MSG_SIZE (sizeof(struct cn_msg) + sizeof(struct proc_event)) ++/* ++ * Size of a cn_msg followed by a proc_event structure. Since the ++ * sizeof struct cn_msg is a multiple of 4 bytes, but not 8 bytes, we ++ * add one 4-byte word to the size here, and then start the actual ++ * cn_msg structure 4 bytes into the stack buffer. The result is that ++ * the immediately following proc_event structure is aligned to 8 bytes. ++ */ ++#define CN_PROC_MSG_SIZE (sizeof(struct cn_msg) + sizeof(struct proc_event) + 4) ++ ++/* See comment above; we test our assumption about sizeof struct cn_msg here. */ ++static inline struct cn_msg *buffer_to_cn_msg(__u8 *buffer) ++{ ++ BUILD_BUG_ON(sizeof(struct cn_msg) != 20); ++ return (struct cn_msg *)(buffer + 4); ++} + + static atomic_t proc_event_num_listeners = ATOMIC_INIT(0); + static struct cb_id cn_proc_event_id = { CN_IDX_PROC, CN_VAL_PROC }; +@@ -55,19 +67,19 @@ void proc_fork_connector(struct task_struct *task) + { + struct cn_msg *msg; + struct proc_event *ev; +- __u8 buffer[CN_PROC_MSG_SIZE]; ++ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8); + struct timespec ts; + struct task_struct *parent; + + if (atomic_read(&proc_event_num_listeners) < 1) + return; + +- msg = (struct cn_msg*)buffer; ++ msg = buffer_to_cn_msg(buffer); + ev = (struct proc_event*)msg->data; + memset(&ev->event_data, 0, sizeof(ev->event_data)); + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ +- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); ++ ev->timestamp_ns = timespec_to_ns(&ts); + ev->what = PROC_EVENT_FORK; + rcu_read_lock(); + parent = rcu_dereference(task->real_parent); +@@ -90,17 +102,17 @@ void proc_exec_connector(struct task_struct *task) + struct cn_msg *msg; + struct proc_event *ev; + struct timespec ts; +- __u8 buffer[CN_PROC_MSG_SIZE]; ++ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8); + + if (atomic_read(&proc_event_num_listeners) < 1) + return; + +- msg = (struct cn_msg*)buffer; ++ msg = buffer_to_cn_msg(buffer); + ev = (struct proc_event*)msg->data; + memset(&ev->event_data, 0, sizeof(ev->event_data)); + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ +- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); ++ ev->timestamp_ns = timespec_to_ns(&ts); + ev->what = PROC_EVENT_EXEC; + ev->event_data.exec.process_pid = task->pid; + ev->event_data.exec.process_tgid = task->tgid; +@@ -116,14 +128,14 @@ void proc_id_connector(struct task_struct *task, int which_id) + { + struct cn_msg *msg; + struct proc_event *ev; +- __u8 buffer[CN_PROC_MSG_SIZE]; ++ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8); + struct timespec ts; + const struct cred *cred; + + if (atomic_read(&proc_event_num_listeners) < 1) + return; + +- msg = (struct cn_msg*)buffer; ++ msg = buffer_to_cn_msg(buffer); + ev = (struct proc_event*)msg->data; + memset(&ev->event_data, 0, sizeof(ev->event_data)); + ev->what = which_id; +@@ -144,7 +156,7 @@ void proc_id_connector(struct task_struct *task, int which_id) + rcu_read_unlock(); + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ +- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); ++ ev->timestamp_ns = timespec_to_ns(&ts); + + memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); + msg->ack = 0; /* not used */ +@@ -158,17 +170,17 @@ void proc_sid_connector(struct task_struct *task) + struct cn_msg *msg; + struct proc_event *ev; + struct timespec ts; +- __u8 buffer[CN_PROC_MSG_SIZE]; ++ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8); + + if (atomic_read(&proc_event_num_listeners) < 1) + return; + +- msg = (struct cn_msg *)buffer; ++ msg = buffer_to_cn_msg(buffer); + ev = (struct proc_event *)msg->data; + memset(&ev->event_data, 0, sizeof(ev->event_data)); + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ +- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); ++ ev->timestamp_ns = timespec_to_ns(&ts); + ev->what = PROC_EVENT_SID; + ev->event_data.sid.process_pid = task->pid; + ev->event_data.sid.process_tgid = task->tgid; +@@ -185,17 +197,17 @@ void proc_ptrace_connector(struct task_struct *task, int ptrace_id) + struct cn_msg *msg; + struct proc_event *ev; + struct timespec ts; +- __u8 buffer[CN_PROC_MSG_SIZE]; ++ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8); + + if (atomic_read(&proc_event_num_listeners) < 1) + return; + +- msg = (struct cn_msg *)buffer; ++ msg = buffer_to_cn_msg(buffer); + ev = (struct proc_event *)msg->data; + memset(&ev->event_data, 0, sizeof(ev->event_data)); + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ +- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); ++ ev->timestamp_ns = timespec_to_ns(&ts); + ev->what = PROC_EVENT_PTRACE; + ev->event_data.ptrace.process_pid = task->pid; + ev->event_data.ptrace.process_tgid = task->tgid; +@@ -220,17 +232,17 @@ void proc_comm_connector(struct task_struct *task) + struct cn_msg *msg; + struct proc_event *ev; + struct timespec ts; +- __u8 buffer[CN_PROC_MSG_SIZE]; ++ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8); + + if (atomic_read(&proc_event_num_listeners) < 1) + return; + +- msg = (struct cn_msg *)buffer; ++ msg = buffer_to_cn_msg(buffer); + ev = (struct proc_event *)msg->data; + memset(&ev->event_data, 0, sizeof(ev->event_data)); + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ +- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); ++ ev->timestamp_ns = timespec_to_ns(&ts); + ev->what = PROC_EVENT_COMM; + ev->event_data.comm.process_pid = task->pid; + ev->event_data.comm.process_tgid = task->tgid; +@@ -247,18 +259,18 @@ void proc_exit_connector(struct task_struct *task) + { + struct cn_msg *msg; + struct proc_event *ev; +- __u8 buffer[CN_PROC_MSG_SIZE]; ++ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8); + struct timespec ts; + + if (atomic_read(&proc_event_num_listeners) < 1) + return; + +- msg = (struct cn_msg*)buffer; ++ msg = buffer_to_cn_msg(buffer); + ev = (struct proc_event*)msg->data; + memset(&ev->event_data, 0, sizeof(ev->event_data)); + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ +- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); ++ ev->timestamp_ns = timespec_to_ns(&ts); + ev->what = PROC_EVENT_EXIT; + ev->event_data.exit.process_pid = task->pid; + ev->event_data.exit.process_tgid = task->tgid; +@@ -284,18 +296,18 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack) + { + struct cn_msg *msg; + struct proc_event *ev; +- __u8 buffer[CN_PROC_MSG_SIZE]; ++ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8); + struct timespec ts; + + if (atomic_read(&proc_event_num_listeners) < 1) + return; + +- msg = (struct cn_msg*)buffer; ++ msg = buffer_to_cn_msg(buffer); + ev = (struct proc_event*)msg->data; + memset(&ev->event_data, 0, sizeof(ev->event_data)); + msg->seq = rcvd_seq; + ktime_get_ts(&ts); /* get high res monotonic timestamp */ +- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); ++ ev->timestamp_ns = timespec_to_ns(&ts); + ev->cpu = -1; + ev->what = PROC_EVENT_NONE; + ev->event_data.ack.err = err; +diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c +index 45c3433f7986..95f90479f285 100644 +--- a/drivers/hid/hid-picolcd.c ++++ b/drivers/hid/hid-picolcd.c +@@ -1424,7 +1424,7 @@ static ssize_t picolcd_operation_mode_store(struct device *dev, + buf += 10; + cnt -= 10; + } +- if (!report) ++ if (!report || report->maxfield != 1) + return -EINVAL; + + while (cnt > 0 && (buf[cnt-1] == '\n' || buf[cnt-1] == '\r')) +diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c +index a60a54d8593a..abc6ac855598 100644 +--- a/drivers/iommu/intel-iommu.c ++++ b/drivers/iommu/intel-iommu.c +@@ -778,7 +778,11 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, + int offset; + + BUG_ON(!domain->pgd); +- BUG_ON(addr_width < BITS_PER_LONG && pfn >> addr_width); ++ ++ if (addr_width < BITS_PER_LONG && pfn >> addr_width) ++ /* Address beyond IOMMU's addressing capabilities. */ ++ return NULL; ++ + parent = domain->pgd; + + while (level > 0) { +diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c +index baf2686aa8eb..02125e6a9109 100644 +--- a/drivers/isdn/isdnloop/isdnloop.c ++++ b/drivers/isdn/isdnloop/isdnloop.c +@@ -1083,8 +1083,10 @@ isdnloop_start(isdnloop_card *card, isdnloop_sdef *sdefp) + spin_unlock_irqrestore(&card->isdnloop_lock, flags); + return -ENOMEM; + } +- for (i = 0; i < 3; i++) +- strcpy(card->s0num[i], sdef.num[i]); ++ for (i = 0; i < 3; i++) { ++ strlcpy(card->s0num[i], sdef.num[i], ++ sizeof(card->s0num[0])); ++ } + break; + case ISDN_PTYPE_1TR6: + if (isdnloop_fake(card, "DRV1.04TC-1TR6-CAPI-CNS-BASIS-29.11.95", +@@ -1097,7 +1099,7 @@ isdnloop_start(isdnloop_card *card, isdnloop_sdef *sdefp) + spin_unlock_irqrestore(&card->isdnloop_lock, flags); + return -ENOMEM; + } +- strcpy(card->s0num[0], sdef.num[0]); ++ strlcpy(card->s0num[0], sdef.num[0], sizeof(card->s0num[0])); + card->s0num[1][0] = '\0'; + card->s0num[2][0] = '\0'; + break; +diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c +index abe2d699b6f3..ade1bcfb0e6d 100644 +--- a/drivers/isdn/mISDN/socket.c ++++ b/drivers/isdn/mISDN/socket.c +@@ -117,7 +117,6 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock, + { + struct sk_buff *skb; + struct sock *sk = sock->sk; +- struct sockaddr_mISDN *maddr; + + int copied, err; + +@@ -135,9 +134,9 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock, + if (!skb) + return err; + +- if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) { +- msg->msg_namelen = sizeof(struct sockaddr_mISDN); +- maddr = (struct sockaddr_mISDN *)msg->msg_name; ++ if (msg->msg_name) { ++ struct sockaddr_mISDN *maddr = msg->msg_name; ++ + maddr->family = AF_ISDN; + maddr->dev = _pms(sk)->dev->id; + if ((sk->sk_protocol == ISDN_P_LAPD_TE) || +@@ -150,11 +149,7 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock, + maddr->sapi = _pms(sk)->ch.addr & 0xFF; + maddr->tei = (_pms(sk)->ch.addr >> 8) & 0xFF; + } +- } else { +- if (msg->msg_namelen) +- printk(KERN_WARNING "%s: too small namelen %d\n", +- __func__, msg->msg_namelen); +- msg->msg_namelen = 0; ++ msg->msg_namelen = sizeof(*maddr); + } + + copied = skb->len + MISDN_HEADER_LEN; +diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c +index 3f06df59fd82..535c3e276fc7 100644 +--- a/drivers/md/dm-crypt.c ++++ b/drivers/md/dm-crypt.c +@@ -1262,20 +1262,6 @@ static int crypt_decode_key(u8 *key, char *hex, unsigned int size) + return 0; + } + +-/* +- * Encode key into its hex representation +- */ +-static void crypt_encode_key(char *hex, u8 *key, unsigned int size) +-{ +- unsigned int i; +- +- for (i = 0; i < size; i++) { +- sprintf(hex, "%02x", *key); +- hex += 2; +- key++; +- } +-} +- + static void crypt_free_tfms(struct crypt_config *cc) + { + unsigned i; +@@ -1741,11 +1727,11 @@ static int crypt_map(struct dm_target *ti, struct bio *bio, + return DM_MAPIO_SUBMITTED; + } + +-static int crypt_status(struct dm_target *ti, status_type_t type, +- char *result, unsigned int maxlen) ++static void crypt_status(struct dm_target *ti, status_type_t type, ++ char *result, unsigned int maxlen) + { + struct crypt_config *cc = ti->private; +- unsigned int sz = 0; ++ unsigned i, sz = 0; + + switch (type) { + case STATUSTYPE_INFO: +@@ -1755,17 +1741,11 @@ static int crypt_status(struct dm_target *ti, status_type_t type, + case STATUSTYPE_TABLE: + DMEMIT("%s ", cc->cipher_string); + +- if (cc->key_size > 0) { +- if ((maxlen - sz) < ((cc->key_size << 1) + 1)) +- return -ENOMEM; +- +- crypt_encode_key(result + sz, cc->key, cc->key_size); +- sz += cc->key_size << 1; +- } else { +- if (sz >= maxlen) +- return -ENOMEM; +- result[sz++] = '-'; +- } ++ if (cc->key_size > 0) ++ for (i = 0; i < cc->key_size; i++) ++ DMEMIT("%02x", cc->key[i]); ++ else ++ DMEMIT("-"); + + DMEMIT(" %llu %s %llu", (unsigned long long)cc->iv_offset, + cc->dev->name, (unsigned long long)cc->start); +@@ -1775,7 +1755,6 @@ static int crypt_status(struct dm_target *ti, status_type_t type, + + break; + } +- return 0; + } + + static void crypt_postsuspend(struct dm_target *ti) +diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c +index 2dc22dddb2ae..ee99912596cb 100644 +--- a/drivers/md/dm-delay.c ++++ b/drivers/md/dm-delay.c +@@ -294,8 +294,8 @@ static int delay_map(struct dm_target *ti, struct bio *bio, + return delay_bio(dc, dc->read_delay, bio); + } + +-static int delay_status(struct dm_target *ti, status_type_t type, +- char *result, unsigned maxlen) ++static void delay_status(struct dm_target *ti, status_type_t type, ++ char *result, unsigned maxlen) + { + struct delay_c *dc = ti->private; + int sz = 0; +@@ -315,8 +315,6 @@ static int delay_status(struct dm_target *ti, status_type_t type, + dc->write_delay); + break; + } +- +- return 0; + } + + static int delay_iterate_devices(struct dm_target *ti, +diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c +index ac49c01f1a44..f29d665fe83a 100644 +--- a/drivers/md/dm-flakey.c ++++ b/drivers/md/dm-flakey.c +@@ -332,8 +332,8 @@ static int flakey_end_io(struct dm_target *ti, struct bio *bio, + return error; + } + +-static int flakey_status(struct dm_target *ti, status_type_t type, +- char *result, unsigned int maxlen) ++static void flakey_status(struct dm_target *ti, status_type_t type, ++ char *result, unsigned int maxlen) + { + unsigned sz = 0; + struct flakey_c *fc = ti->private; +@@ -363,7 +363,6 @@ static int flakey_status(struct dm_target *ti, status_type_t type, + + break; + } +- return 0; + } + + static int flakey_ioctl(struct dm_target *ti, unsigned int cmd, unsigned long arg) +diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c +index f011d4b3c139..d365365bdb99 100644 +--- a/drivers/md/dm-ioctl.c ++++ b/drivers/md/dm-ioctl.c +@@ -1066,6 +1066,7 @@ static void retrieve_status(struct dm_table *table, + num_targets = dm_table_get_num_targets(table); + for (i = 0; i < num_targets; i++) { + struct dm_target *ti = dm_table_get_target(table, i); ++ size_t l; + + remaining = len - (outptr - outbuf); + if (remaining <= sizeof(struct dm_target_spec)) { +@@ -1089,15 +1090,18 @@ static void retrieve_status(struct dm_table *table, + } + + /* Get the status/table string from the target driver */ +- if (ti->type->status) { +- if (ti->type->status(ti, type, outptr, remaining)) { +- param->flags |= DM_BUFFER_FULL_FLAG; +- break; +- } +- } else ++ if (ti->type->status) ++ ti->type->status(ti, type, outptr, remaining); ++ else + outptr[0] = '\0'; + +- outptr += strlen(outptr) + 1; ++ l = strlen(outptr) + 1; ++ if (l == remaining) { ++ param->flags |= DM_BUFFER_FULL_FLAG; ++ break; ++ } ++ ++ outptr += l; + used = param->data_start + (outptr - outbuf); + + outptr = align_ptr(outptr); +diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c +index 3639eeab6042..5a5e9c8b29a7 100644 +--- a/drivers/md/dm-linear.c ++++ b/drivers/md/dm-linear.c +@@ -95,8 +95,8 @@ static int linear_map(struct dm_target *ti, struct bio *bio, + return DM_MAPIO_REMAPPED; + } + +-static int linear_status(struct dm_target *ti, status_type_t type, +- char *result, unsigned int maxlen) ++static void linear_status(struct dm_target *ti, status_type_t type, ++ char *result, unsigned int maxlen) + { + struct linear_c *lc = (struct linear_c *) ti->private; + +@@ -110,7 +110,6 @@ static int linear_status(struct dm_target *ti, status_type_t type, + (unsigned long long)lc->start); + break; + } +- return 0; + } + + static int linear_ioctl(struct dm_target *ti, unsigned int cmd, +diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c +index 754f38f8a692..b74cb796c17c 100644 +--- a/drivers/md/dm-mpath.c ++++ b/drivers/md/dm-mpath.c +@@ -1343,8 +1343,8 @@ static void multipath_resume(struct dm_target *ti) + * [priority selector-name num_ps_args [ps_args]* + * num_paths num_selector_args [path_dev [selector_args]* ]+ ]+ + */ +-static int multipath_status(struct dm_target *ti, status_type_t type, +- char *result, unsigned int maxlen) ++static void multipath_status(struct dm_target *ti, status_type_t type, ++ char *result, unsigned int maxlen) + { + int sz = 0; + unsigned long flags; +@@ -1447,8 +1447,6 @@ static int multipath_status(struct dm_target *ti, status_type_t type, + } + + spin_unlock_irqrestore(&m->lock, flags); +- +- return 0; + } + + static int multipath_message(struct dm_target *ti, unsigned argc, char **argv) +diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c +index 68965e663248..ead5ca99a749 100644 +--- a/drivers/md/dm-raid.c ++++ b/drivers/md/dm-raid.c +@@ -1067,8 +1067,8 @@ static int raid_map(struct dm_target *ti, struct bio *bio, union map_info *map_c + return DM_MAPIO_SUBMITTED; + } + +-static int raid_status(struct dm_target *ti, status_type_t type, +- char *result, unsigned maxlen) ++static void raid_status(struct dm_target *ti, status_type_t type, ++ char *result, unsigned maxlen) + { + struct raid_set *rs = ti->private; + unsigned raid_param_cnt = 1; /* at least 1 for chunksize */ +@@ -1203,8 +1203,6 @@ static int raid_status(struct dm_target *ti, status_type_t type, + DMEMIT(" -"); + } + } +- +- return 0; + } + + static int raid_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data) +diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c +index b58b7a33914a..a3cf259275af 100644 +--- a/drivers/md/dm-raid1.c ++++ b/drivers/md/dm-raid1.c +@@ -1362,8 +1362,8 @@ static char device_status_char(struct mirror *m) + } + + +-static int mirror_status(struct dm_target *ti, status_type_t type, +- char *result, unsigned int maxlen) ++static void mirror_status(struct dm_target *ti, status_type_t type, ++ char *result, unsigned int maxlen) + { + unsigned int m, sz = 0; + struct mirror_set *ms = (struct mirror_set *) ti->private; +@@ -1398,8 +1398,6 @@ static int mirror_status(struct dm_target *ti, status_type_t type, + if (ms->features & DM_RAID1_HANDLE_ERRORS) + DMEMIT(" 1 handle_errors"); + } +- +- return 0; + } + + static int mirror_iterate_devices(struct dm_target *ti, +diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c +index 448050c87be0..db77ac693323 100644 +--- a/drivers/md/dm-snap.c ++++ b/drivers/md/dm-snap.c +@@ -1845,8 +1845,8 @@ static void snapshot_merge_resume(struct dm_target *ti) + start_merge(s); + } + +-static int snapshot_status(struct dm_target *ti, status_type_t type, +- char *result, unsigned int maxlen) ++static void snapshot_status(struct dm_target *ti, status_type_t type, ++ char *result, unsigned int maxlen) + { + unsigned sz = 0; + struct dm_snapshot *snap = ti->private; +@@ -1892,8 +1892,6 @@ static int snapshot_status(struct dm_target *ti, status_type_t type, + maxlen - sz); + break; + } +- +- return 0; + } + + static int snapshot_iterate_devices(struct dm_target *ti, +@@ -2148,8 +2146,8 @@ static void origin_resume(struct dm_target *ti) + ti->split_io = get_origin_minimum_chunksize(dev->bdev); + } + +-static int origin_status(struct dm_target *ti, status_type_t type, char *result, +- unsigned int maxlen) ++static void origin_status(struct dm_target *ti, status_type_t type, char *result, ++ unsigned int maxlen) + { + struct dm_dev *dev = ti->private; + +@@ -2162,8 +2160,6 @@ static int origin_status(struct dm_target *ti, status_type_t type, char *result, + snprintf(result, maxlen, "%s", dev->name); + break; + } +- +- return 0; + } + + static int origin_merge(struct dm_target *ti, struct bvec_merge_data *bvm, +diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c +index 35c94ff24ad5..58ffcda3dab3 100644 +--- a/drivers/md/dm-stripe.c ++++ b/drivers/md/dm-stripe.c +@@ -302,8 +302,8 @@ static int stripe_map(struct dm_target *ti, struct bio *bio, + * + */ + +-static int stripe_status(struct dm_target *ti, +- status_type_t type, char *result, unsigned int maxlen) ++static void stripe_status(struct dm_target *ti, ++ status_type_t type, char *result, unsigned int maxlen) + { + struct stripe_c *sc = (struct stripe_c *) ti->private; + char buffer[sc->stripes + 1]; +@@ -330,7 +330,6 @@ static int stripe_status(struct dm_target *ti, + (unsigned long long)sc->stripe[i].physical_start); + break; + } +- return 0; + } + + static int stripe_end_io(struct dm_target *ti, struct bio *bio, +diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c +index 7c3ab8fcdbd3..c540dfff1f81 100644 +--- a/drivers/md/dm-thin.c ++++ b/drivers/md/dm-thin.c +@@ -2325,8 +2325,8 @@ static int pool_message(struct dm_target *ti, unsigned argc, char **argv) + * / + * / + */ +-static int pool_status(struct dm_target *ti, status_type_t type, +- char *result, unsigned maxlen) ++static void pool_status(struct dm_target *ti, status_type_t type, ++ char *result, unsigned maxlen) + { + int r, count; + unsigned sz = 0; +@@ -2343,32 +2343,41 @@ static int pool_status(struct dm_target *ti, status_type_t type, + + switch (type) { + case STATUSTYPE_INFO: +- r = dm_pool_get_metadata_transaction_id(pool->pmd, +- &transaction_id); +- if (r) +- return r; ++ r = dm_pool_get_metadata_transaction_id(pool->pmd, &transaction_id); ++ if (r) { ++ DMERR("dm_pool_get_metadata_transaction_id returned %d", r); ++ goto err; ++ } + +- r = dm_pool_get_free_metadata_block_count(pool->pmd, +- &nr_free_blocks_metadata); +- if (r) +- return r; ++ r = dm_pool_get_free_metadata_block_count(pool->pmd, &nr_free_blocks_metadata); ++ if (r) { ++ DMERR("dm_pool_get_free_metadata_block_count returned %d", r); ++ goto err; ++ } + + r = dm_pool_get_metadata_dev_size(pool->pmd, &nr_blocks_metadata); +- if (r) +- return r; ++ if (r) { ++ DMERR("dm_pool_get_metadata_dev_size returned %d", r); ++ goto err; ++ } + +- r = dm_pool_get_free_block_count(pool->pmd, +- &nr_free_blocks_data); +- if (r) +- return r; ++ r = dm_pool_get_free_block_count(pool->pmd, &nr_free_blocks_data); ++ if (r) { ++ DMERR("dm_pool_get_free_block_count returned %d", r); ++ goto err; ++ } + + r = dm_pool_get_data_dev_size(pool->pmd, &nr_blocks_data); +- if (r) +- return r; ++ if (r) { ++ DMERR("dm_pool_get_data_dev_size returned %d", r); ++ goto err; ++ } + + r = dm_pool_get_held_metadata_root(pool->pmd, &held_root); +- if (r) +- return r; ++ if (r) { ++ DMERR("dm_pool_get_metadata_snap returned %d", r); ++ goto err; ++ } + + DMEMIT("%llu %llu/%llu %llu/%llu ", + (unsigned long long)transaction_id, +@@ -2406,8 +2415,10 @@ static int pool_status(struct dm_target *ti, status_type_t type, + + break; + } ++ return; + +- return 0; ++err: ++ DMEMIT("Error"); + } + + static int pool_iterate_devices(struct dm_target *ti, +@@ -2659,8 +2670,8 @@ static void thin_postsuspend(struct dm_target *ti) + /* + * + */ +-static int thin_status(struct dm_target *ti, status_type_t type, +- char *result, unsigned maxlen) ++static void thin_status(struct dm_target *ti, status_type_t type, ++ char *result, unsigned maxlen) + { + int r; + ssize_t sz = 0; +@@ -2674,12 +2685,16 @@ static int thin_status(struct dm_target *ti, status_type_t type, + switch (type) { + case STATUSTYPE_INFO: + r = dm_thin_get_mapped_count(tc->td, &mapped); +- if (r) +- return r; ++ if (r) { ++ DMERR("dm_thin_get_mapped_count returned %d", r); ++ goto err; ++ } + + r = dm_thin_get_highest_mapped_block(tc->td, &highest); +- if (r < 0) +- return r; ++ if (r < 0) { ++ DMERR("dm_thin_get_highest_mapped_block returned %d", r); ++ goto err; ++ } + + DMEMIT("%llu ", mapped * tc->pool->sectors_per_block); + if (r) +@@ -2699,7 +2714,10 @@ static int thin_status(struct dm_target *ti, status_type_t type, + } + } + +- return 0; ++ return; ++ ++err: ++ DMEMIT("Error"); + } + + static int thin_iterate_devices(struct dm_target *ti, +diff --git a/drivers/md/dm-verity.c b/drivers/md/dm-verity.c +index 9ab2a6a582b6..ac099847a4b3 100644 +--- a/drivers/md/dm-verity.c ++++ b/drivers/md/dm-verity.c +@@ -514,8 +514,8 @@ static int verity_map(struct dm_target *ti, struct bio *bio, + /* + * Status: V (valid) or C (corruption found) + */ +-static int verity_status(struct dm_target *ti, status_type_t type, +- char *result, unsigned maxlen) ++static void verity_status(struct dm_target *ti, status_type_t type, ++ char *result, unsigned maxlen) + { + struct dm_verity *v = ti->private; + unsigned sz = 0; +@@ -546,8 +546,6 @@ static int verity_status(struct dm_target *ti, status_type_t type, + DMEMIT("%02x", v->salt[x]); + break; + } +- +- return 0; + } + + static int verity_ioctl(struct dm_target *ti, unsigned cmd, +diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c +index 833ff16f5fe1..c32a9093159a 100644 +--- a/drivers/mmc/card/block.c ++++ b/drivers/mmc/card/block.c +@@ -701,7 +701,7 @@ static int mmc_blk_cmd_error(struct request *req, const char *name, int error, + * Otherwise we don't understand what happened, so abort. + */ + static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req, +- struct mmc_blk_request *brq, int *ecc_err) ++ struct mmc_blk_request *brq, int *ecc_err, int *gen_err) + { + bool prev_cmd_status_valid = true; + u32 status, stop_status = 0; +@@ -739,6 +739,16 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req, + (brq->cmd.resp[0] & R1_CARD_ECC_FAILED)) + *ecc_err = 1; + ++ /* Flag General errors */ ++ if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) ++ if ((status & R1_ERROR) || ++ (brq->stop.resp[0] & R1_ERROR)) { ++ pr_err("%s: %s: general error sending stop or status command, stop cmd response %#x, card status %#x\n", ++ req->rq_disk->disk_name, __func__, ++ brq->stop.resp[0], status); ++ *gen_err = 1; ++ } ++ + /* + * Check the current card state. If it is in some data transfer + * mode, tell it to stop (and hopefully transition back to TRAN.) +@@ -758,6 +768,13 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req, + return ERR_ABORT; + if (stop_status & R1_CARD_ECC_FAILED) + *ecc_err = 1; ++ if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) ++ if (stop_status & R1_ERROR) { ++ pr_err("%s: %s: general error sending stop command, stop cmd response %#x\n", ++ req->rq_disk->disk_name, __func__, ++ stop_status); ++ *gen_err = 1; ++ } + } + + /* Check for set block count errors */ +@@ -1007,7 +1024,7 @@ static int mmc_blk_err_check(struct mmc_card *card, + mmc_active); + struct mmc_blk_request *brq = &mq_mrq->brq; + struct request *req = mq_mrq->req; +- int ecc_err = 0; ++ int ecc_err = 0, gen_err = 0; + + /* + * sbc.error indicates a problem with the set block count +@@ -1021,7 +1038,7 @@ static int mmc_blk_err_check(struct mmc_card *card, + */ + if (brq->sbc.error || brq->cmd.error || brq->stop.error || + brq->data.error) { +- switch (mmc_blk_cmd_recovery(card, req, brq, &ecc_err)) { ++ switch (mmc_blk_cmd_recovery(card, req, brq, &ecc_err, &gen_err)) { + case ERR_RETRY: + return MMC_BLK_RETRY; + case ERR_ABORT: +@@ -1051,6 +1068,15 @@ static int mmc_blk_err_check(struct mmc_card *card, + */ + if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) { + u32 status; ++ ++ /* Check stop command response */ ++ if (brq->stop.resp[0] & R1_ERROR) { ++ pr_err("%s: %s: general error sending stop command, stop cmd response %#x\n", ++ req->rq_disk->disk_name, __func__, ++ brq->stop.resp[0]); ++ gen_err = 1; ++ } ++ + do { + int err = get_card_status(card, &status, 5); + if (err) { +@@ -1058,6 +1084,14 @@ static int mmc_blk_err_check(struct mmc_card *card, + req->rq_disk->disk_name, err); + return MMC_BLK_CMD_ERR; + } ++ ++ if (status & R1_ERROR) { ++ pr_err("%s: %s: general error sending status command, card status %#x\n", ++ req->rq_disk->disk_name, __func__, ++ status); ++ gen_err = 1; ++ } ++ + /* + * Some cards mishandle the status bits, + * so make sure to check both the busy +@@ -1067,6 +1101,13 @@ static int mmc_blk_err_check(struct mmc_card *card, + (R1_CURRENT_STATE(status) == R1_STATE_PRG)); + } + ++ /* if general error occurs, retry the write operation. */ ++ if (gen_err) { ++ pr_warning("%s: retrying write for general error\n", ++ req->rq_disk->disk_name); ++ return MMC_BLK_RETRY; ++ } ++ + if (brq->data.error) { + pr_err("%s: error %d transferring data, sector %u, nr %u, cmd response %#x, card status %#x\n", + req->rq_disk->disk_name, brq->data.error, +diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c +index c40c0a871818..f42a00ac38d7 100644 +--- a/drivers/net/bonding/bond_sysfs.c ++++ b/drivers/net/bonding/bond_sysfs.c +@@ -533,8 +533,9 @@ static ssize_t bonding_store_arp_interval(struct device *d, + goto out; + } + if (bond->params.mode == BOND_MODE_ALB || +- bond->params.mode == BOND_MODE_TLB) { +- pr_info("%s: ARP monitoring cannot be used with ALB/TLB. Only MII monitoring is supported on %s.\n", ++ bond->params.mode == BOND_MODE_TLB || ++ bond->params.mode == BOND_MODE_8023AD) { ++ pr_info("%s: ARP monitoring cannot be used with ALB/TLB/802.3ad. Only MII monitoring is supported on %s.\n", + bond->dev->name, bond->dev->name); + ret = -EINVAL; + goto out; +@@ -692,6 +693,8 @@ static ssize_t bonding_store_downdelay(struct device *d, + int new_value, ret = count; + struct bonding *bond = to_bond(d); + ++ if (!rtnl_trylock()) ++ return restart_syscall(); + if (!(bond->params.miimon)) { + pr_err("%s: Unable to set down delay as MII monitoring is disabled\n", + bond->dev->name); +@@ -725,6 +728,7 @@ static ssize_t bonding_store_downdelay(struct device *d, + } + + out: ++ rtnl_unlock(); + return ret; + } + static DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR, +@@ -747,6 +751,8 @@ static ssize_t bonding_store_updelay(struct device *d, + int new_value, ret = count; + struct bonding *bond = to_bond(d); + ++ if (!rtnl_trylock()) ++ return restart_syscall(); + if (!(bond->params.miimon)) { + pr_err("%s: Unable to set up delay as MII monitoring is disabled\n", + bond->dev->name); +@@ -780,6 +786,7 @@ static ssize_t bonding_store_updelay(struct device *d, + } + + out: ++ rtnl_unlock(); + return ret; + } + static DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR, +diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c +index 2e0d8762bb52..bac88c22d990 100644 +--- a/drivers/net/ppp/pppoe.c ++++ b/drivers/net/ppp/pppoe.c +@@ -985,8 +985,6 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock, + if (error < 0) + goto end; + +- m->msg_namelen = 0; +- + if (skb) { + total_len = min_t(size_t, total_len, skb->len); + error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len); +diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/kyro/fbdev.c +index acb9370fdb14..7aa8668f0a0c 100644 +--- a/drivers/video/kyro/fbdev.c ++++ b/drivers/video/kyro/fbdev.c +@@ -625,15 +625,15 @@ static int kyrofb_ioctl(struct fb_info *info, + } + break; + case KYRO_IOCTL_UVSTRIDE: +- if (copy_to_user(argp, &deviceInfo.ulOverlayUVStride, sizeof(unsigned long))) ++ if (copy_to_user(argp, &deviceInfo.ulOverlayUVStride, sizeof(deviceInfo.ulOverlayUVStride))) + return -EFAULT; + break; + case KYRO_IOCTL_STRIDE: +- if (copy_to_user(argp, &deviceInfo.ulOverlayStride, sizeof(unsigned long))) ++ if (copy_to_user(argp, &deviceInfo.ulOverlayStride, sizeof(deviceInfo.ulOverlayStride))) + return -EFAULT; + break; + case KYRO_IOCTL_OVERLAY_OFFSET: +- if (copy_to_user(argp, &deviceInfo.ulOverlayOffset, sizeof(unsigned long))) ++ if (copy_to_user(argp, &deviceInfo.ulOverlayOffset, sizeof(deviceInfo.ulOverlayOffset))) + return -EFAULT; + break; + } +diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c +index 53459b055cfc..25d839ed0ae1 100644 +--- a/fs/nfsd/nfssvc.c ++++ b/fs/nfsd/nfssvc.c +@@ -11,7 +11,6 @@ + #include + #include + #include +-#include + + #include + #include +@@ -330,7 +329,7 @@ static int nfsd_get_default_max_blksize(void) + int nfsd_create_serv(void) + { + int error; +- struct net *net = current->nsproxy->net_ns; ++ struct net *net = &init_net; + + WARN_ON(!mutex_is_locked(&nfsd_mutex)); + if (nfsd_serv) { +diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h +index 98f34b886f95..fa09b579f67c 100644 +--- a/include/linux/device-mapper.h ++++ b/include/linux/device-mapper.h +@@ -72,8 +72,8 @@ typedef void (*dm_postsuspend_fn) (struct dm_target *ti); + typedef int (*dm_preresume_fn) (struct dm_target *ti); + typedef void (*dm_resume_fn) (struct dm_target *ti); + +-typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type, +- char *result, unsigned int maxlen); ++typedef void (*dm_status_fn) (struct dm_target *ti, status_type_t status_type, ++ char *result, unsigned int maxlen); + + typedef int (*dm_message_fn) (struct dm_target *ti, unsigned argc, char **argv); + +diff --git a/include/linux/net.h b/include/linux/net.h +index 95fea1432dd3..45232814fc03 100644 +--- a/include/linux/net.h ++++ b/include/linux/net.h +@@ -198,6 +198,14 @@ struct proto_ops { + #endif + int (*sendmsg) (struct kiocb *iocb, struct socket *sock, + struct msghdr *m, size_t total_len); ++ /* Notes for implementing recvmsg: ++ * =============================== ++ * msg->msg_namelen should get updated by the recvmsg handlers ++ * iff msg_name != NULL. It is by default 0 to prevent ++ * returning uninitialized memory to user space. The recvfrom ++ * handlers can assume that msg.msg_name is either NULL or has ++ * a minimum size of sizeof(struct sockaddr_storage). ++ */ + int (*recvmsg) (struct kiocb *iocb, struct socket *sock, + struct msghdr *m, size_t total_len, + int flags); +diff --git a/include/linux/random.h b/include/linux/random.h +index 7e58ad27b7ff..54b1fd3efdfa 100644 +--- a/include/linux/random.h ++++ b/include/linux/random.h +@@ -87,9 +87,9 @@ static inline void prandom32_seed(struct rnd_state *state, u64 seed) + { + u32 i = (seed >> 32) ^ (seed << 10) ^ seed; + +- state->s1 = __seed(i, 1); +- state->s2 = __seed(i, 7); +- state->s3 = __seed(i, 15); ++ state->s1 = __seed(i, 2); ++ state->s2 = __seed(i, 8); ++ state->s3 = __seed(i, 16); + } + + #ifdef CONFIG_ARCH_RANDOM +diff --git a/include/net/ip.h b/include/net/ip.h +index 0750bf7d424f..6d6b12f4753c 100644 +--- a/include/net/ip.h ++++ b/include/net/ip.h +@@ -466,7 +466,7 @@ extern int compat_ip_getsockopt(struct sock *sk, int level, + int optname, char __user *optval, int __user *optlen); + extern int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *)); + +-extern int ip_recv_error(struct sock *sk, struct msghdr *msg, int len); ++extern int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len); + extern void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err, + __be16 port, u32 info, u8 *payload); + extern void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport, +diff --git a/include/net/ipv6.h b/include/net/ipv6.h +index 12a1bd2e9879..fa7af9183dc9 100644 +--- a/include/net/ipv6.h ++++ b/include/net/ipv6.h +@@ -606,8 +606,10 @@ extern int compat_ipv6_getsockopt(struct sock *sk, + extern int ip6_datagram_connect(struct sock *sk, + struct sockaddr *addr, int addr_len); + +-extern int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len); +-extern int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len); ++extern int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, ++ int *addr_len); ++extern int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len, ++ int *addr_len); + extern void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port, + u32 info, u8 *payload); + extern void ipv6_local_error(struct sock *sk, int err, struct flowi6 *fl6, u32 info); +diff --git a/lib/random32.c b/lib/random32.c +index 938bde5876ac..aa95712c1431 100644 +--- a/lib/random32.c ++++ b/lib/random32.c +@@ -92,7 +92,7 @@ void srandom32(u32 entropy) + */ + for_each_possible_cpu (i) { + struct rnd_state *state = &per_cpu(net_rand_state, i); +- state->s1 = __seed(state->s1 ^ entropy, 1); ++ state->s1 = __seed(state->s1 ^ entropy, 2); + } + } + EXPORT_SYMBOL(srandom32); +@@ -109,9 +109,9 @@ static int __init random32_init(void) + struct rnd_state *state = &per_cpu(net_rand_state,i); + + #define LCG(x) ((x) * 69069) /* super-duper LCG */ +- state->s1 = __seed(LCG(i + jiffies), 1); +- state->s2 = __seed(LCG(state->s1), 7); +- state->s3 = __seed(LCG(state->s2), 15); ++ state->s1 = __seed(LCG(i + jiffies), 2); ++ state->s2 = __seed(LCG(state->s1), 8); ++ state->s3 = __seed(LCG(state->s2), 16); + + /* "warm it up" */ + prandom32(state); +@@ -138,9 +138,9 @@ static int __init random32_reseed(void) + u32 seeds[3]; + + get_random_bytes(&seeds, sizeof(seeds)); +- state->s1 = __seed(seeds[0], 1); +- state->s2 = __seed(seeds[1], 7); +- state->s3 = __seed(seeds[2], 15); ++ state->s1 = __seed(seeds[0], 2); ++ state->s2 = __seed(seeds[1], 8); ++ state->s3 = __seed(seeds[2], 16); + + /* mix it in */ + prandom32(state); +diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c +index bfa9ab93eda5..334d4cd7612f 100644 +--- a/net/appletalk/ddp.c ++++ b/net/appletalk/ddp.c +@@ -1740,7 +1740,6 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr + size_t size, int flags) + { + struct sock *sk = sock->sk; +- struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name; + struct ddpehdr *ddp; + int copied = 0; + int offset = 0; +@@ -1769,14 +1768,13 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr + } + err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied); + +- if (!err) { +- if (sat) { +- sat->sat_family = AF_APPLETALK; +- sat->sat_port = ddp->deh_sport; +- sat->sat_addr.s_node = ddp->deh_snode; +- sat->sat_addr.s_net = ddp->deh_snet; +- } +- msg->msg_namelen = sizeof(*sat); ++ if (!err && msg->msg_name) { ++ struct sockaddr_at *sat = msg->msg_name; ++ sat->sat_family = AF_APPLETALK; ++ sat->sat_port = ddp->deh_sport; ++ sat->sat_addr.s_node = ddp->deh_snode; ++ sat->sat_addr.s_net = ddp->deh_snet; ++ msg->msg_namelen = sizeof(*sat); + } + + skb_free_datagram(sk, skb); /* Free the datagram. */ +diff --git a/net/atm/common.c b/net/atm/common.c +index f0a9b7eb3732..0c0ad930a632 100644 +--- a/net/atm/common.c ++++ b/net/atm/common.c +@@ -520,8 +520,6 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, + struct sk_buff *skb; + int copied, error = -EINVAL; + +- msg->msg_namelen = 0; +- + if (sock->state != SS_CONNECTED) + return -ENOTCONN; + +diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c +index 68b39927ecda..ca1820cf22f2 100644 +--- a/net/ax25/af_ax25.c ++++ b/net/ax25/af_ax25.c +@@ -1640,11 +1640,11 @@ static int ax25_recvmsg(struct kiocb *iocb, struct socket *sock, + + skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); + +- if (msg->msg_namelen != 0) { +- struct sockaddr_ax25 *sax = (struct sockaddr_ax25 *)msg->msg_name; ++ if (msg->msg_name) { + ax25_digi digi; + ax25_address src; + const unsigned char *mac = skb_mac_header(skb); ++ struct sockaddr_ax25 *sax = msg->msg_name; + + memset(sax, 0, sizeof(struct full_sockaddr_ax25)); + ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL, +diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c +index c2943484eab4..af3775f3d640 100644 +--- a/net/bluetooth/af_bluetooth.c ++++ b/net/bluetooth/af_bluetooth.c +@@ -240,8 +240,6 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, + if (flags & (MSG_OOB)) + return -EOPNOTSUPP; + +- msg->msg_namelen = 0; +- + skb = skb_recv_datagram(sk, flags, noblock, &err); + if (!skb) { + if (sk->sk_shutdown & RCV_SHUTDOWN) +@@ -306,8 +304,6 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, + if (flags & MSG_OOB) + return -EOPNOTSUPP; + +- msg->msg_namelen = 0; +- + BT_DBG("sk %p size %zu", sk, size); + + lock_sock(sk); +diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c +index bedc768c8cdf..8c2cb05e50ea 100644 +--- a/net/bluetooth/hci_sock.c ++++ b/net/bluetooth/hci_sock.c +@@ -767,8 +767,6 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock, + if (!skb) + return err; + +- msg->msg_namelen = 0; +- + copied = skb->len; + if (len < copied) { + msg->msg_flags |= MSG_TRUNC; +diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c +index c79db7f7533b..8d1edd7207df 100644 +--- a/net/bluetooth/rfcomm/sock.c ++++ b/net/bluetooth/rfcomm/sock.c +@@ -628,7 +628,6 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock, + + if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) { + rfcomm_dlc_accept(d); +- msg->msg_namelen = 0; + return 0; + } + +diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c +index e1144e1617be..ff44f5f16780 100644 +--- a/net/bridge/br_if.c ++++ b/net/bridge/br_if.c +@@ -170,6 +170,8 @@ void br_dev_delete(struct net_device *dev, struct list_head *head) + del_nbp(p); + } + ++ br_fdb_delete_by_port(br, NULL, 1); ++ + del_timer_sync(&br->gc_timer); + + br_sysfs_delbr(br->dev); +diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c +index 24a68861881c..9e8351598f8a 100644 +--- a/net/caif/caif_socket.c ++++ b/net/caif/caif_socket.c +@@ -287,8 +287,6 @@ static int caif_seqpkt_recvmsg(struct kiocb *iocb, struct socket *sock, + if (m->msg_flags&MSG_OOB) + goto read_error; + +- m->msg_namelen = 0; +- + skb = skb_recv_datagram(sk, flags, 0 , &ret); + if (!skb) + goto read_error; +@@ -362,8 +360,6 @@ static int caif_stream_recvmsg(struct kiocb *iocb, struct socket *sock, + if (flags&MSG_OOB) + goto out; + +- msg->msg_namelen = 0; +- + /* + * Lock the socket to prevent queue disordering + * while sleeps in memcpy_tomsg +diff --git a/net/compat.c b/net/compat.c +index ee84d82d7287..17f997e14f63 100644 +--- a/net/compat.c ++++ b/net/compat.c +@@ -72,7 +72,7 @@ int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg) + __get_user(kmsg->msg_flags, &umsg->msg_flags)) + return -EFAULT; + if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) +- return -EINVAL; ++ kmsg->msg_namelen = sizeof(struct sockaddr_storage); + kmsg->msg_name = compat_ptr(tmp1); + kmsg->msg_iov = compat_ptr(tmp2); + kmsg->msg_control = compat_ptr(tmp3); +@@ -93,7 +93,8 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov, + if (err < 0) + return err; + } +- kern_msg->msg_name = kern_address; ++ if (kern_msg->msg_name) ++ kern_msg->msg_name = kern_address; + } else + kern_msg->msg_name = NULL; + +diff --git a/net/core/dev.c b/net/core/dev.c +index 7db83d64e4f7..cebdc15ce327 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -4443,7 +4443,7 @@ static void dev_change_rx_flags(struct net_device *dev, int flags) + { + const struct net_device_ops *ops = dev->netdev_ops; + +- if ((dev->flags & IFF_UP) && ops->ndo_change_rx_flags) ++ if (ops->ndo_change_rx_flags) + ops->ndo_change_rx_flags(dev, flags); + } + +diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c +index c02e63c908da..c0c21b1ce1ec 100644 +--- a/net/core/fib_rules.c ++++ b/net/core/fib_rules.c +@@ -443,7 +443,8 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) + if (frh->action && (frh->action != rule->action)) + continue; + +- if (frh->table && (frh_get_table(frh, tb) != rule->table)) ++ if (frh_get_table(frh, tb) && ++ (frh_get_table(frh, tb) != rule->table)) + continue; + + if (tb[FRA_PRIORITY] && +diff --git a/net/core/iovec.c b/net/core/iovec.c +index 7e7aeb01de45..7fd34a56aeb3 100644 +--- a/net/core/iovec.c ++++ b/net/core/iovec.c +@@ -48,7 +48,8 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *a + if (err < 0) + return err; + } +- m->msg_name = address; ++ if (m->msg_name) ++ m->msg_name = address; + } else { + m->msg_name = NULL; + } +diff --git a/net/core/pktgen.c b/net/core/pktgen.c +index 114d8a9e8570..546b1334fad4 100644 +--- a/net/core/pktgen.c ++++ b/net/core/pktgen.c +@@ -2521,6 +2521,8 @@ static int process_ipsec(struct pktgen_dev *pkt_dev, + if (x) { + int ret; + __u8 *eth; ++ struct iphdr *iph; ++ + nhead = x->props.header_len - skb_headroom(skb); + if (nhead > 0) { + ret = pskb_expand_head(skb, nhead, 0, GFP_ATOMIC); +@@ -2542,6 +2544,11 @@ static int process_ipsec(struct pktgen_dev *pkt_dev, + eth = (__u8 *) skb_push(skb, ETH_HLEN); + memcpy(eth, pkt_dev->hh, 12); + *(u16 *) ð[12] = protocol; ++ ++ /* Update IPv4 header len as well as checksum value */ ++ iph = ip_hdr(skb); ++ iph->tot_len = htons(skb->len - ETH_HLEN); ++ ip_send_check(iph); + } + } + return 1; +diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c +index 840821b90bcd..ddbdceb9594b 100644 +--- a/net/ieee802154/6lowpan.c ++++ b/net/ieee802154/6lowpan.c +@@ -803,7 +803,7 @@ lowpan_process_data(struct sk_buff *skb) + * Traffic class carried in-line + * ECN + DSCP (1 byte), Flow Label is elided + */ +- case 1: /* 10b */ ++ case 2: /* 10b */ + if (!skb->len) + goto drop; + tmp = lowpan_fetch_skb_u8(skb); +@@ -816,7 +816,7 @@ lowpan_process_data(struct sk_buff *skb) + * Flow Label carried in-line + * ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided + */ +- case 2: /* 01b */ ++ case 1: /* 01b */ + if (!skb->len) + goto drop; + tmp = lowpan_fetch_skb_u8(skb); +diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c +index 424fafbc8cb0..ec0751051db7 100644 +--- a/net/ipv4/datagram.c ++++ b/net/ipv4/datagram.c +@@ -57,7 +57,7 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) + if (IS_ERR(rt)) { + err = PTR_ERR(rt); + if (err == -ENETUNREACH) +- IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); ++ IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); + goto out; + } + +diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c +index 374828487003..0bd174faff8f 100644 +--- a/net/ipv4/ip_sockglue.c ++++ b/net/ipv4/ip_sockglue.c +@@ -367,7 +367,7 @@ void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 port, u32 inf + /* + * Handle MSG_ERRQUEUE + */ +-int ip_recv_error(struct sock *sk, struct msghdr *msg, int len) ++int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) + { + struct sock_exterr_skb *serr; + struct sk_buff *skb, *skb2; +@@ -404,6 +404,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len) + serr->addr_offset); + sin->sin_port = serr->port; + memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); ++ *addr_len = sizeof(*sin); + } + + memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); +diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c +index c234bda5b801..e80db1e6b0b2 100644 +--- a/net/ipv4/ping.c ++++ b/net/ipv4/ping.c +@@ -774,7 +774,7 @@ int ping_v4_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, + err = PTR_ERR(rt); + rt = NULL; + if (err == -ENETUNREACH) +- IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); ++ IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES); + goto out; + } + +@@ -852,10 +852,10 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, + + if (flags & MSG_ERRQUEUE) { + if (family == AF_INET) { +- return ip_recv_error(sk, msg, len); ++ return ip_recv_error(sk, msg, len, addr_len); + #if IS_ENABLED(CONFIG_IPV6) + } else if (family == AF_INET6) { +- return pingv6_ops.ipv6_recv_error(sk, msg, len); ++ return pingv6_ops.ipv6_recv_error(sk, msg, len); + #endif + } + } +diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c +index c6b9ca651ab3..48c6ebcb7fe0 100644 +--- a/net/ipv4/raw.c ++++ b/net/ipv4/raw.c +@@ -688,11 +688,8 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, + if (flags & MSG_OOB) + goto out; + +- if (addr_len) +- *addr_len = sizeof(*sin); +- + if (flags & MSG_ERRQUEUE) { +- err = ip_recv_error(sk, msg, len); ++ err = ip_recv_error(sk, msg, len, addr_len); + goto out; + } + +@@ -718,6 +715,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, + sin->sin_addr.s_addr = ip_hdr(skb)->saddr; + sin->sin_port = 0; + memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); ++ *addr_len = sizeof(*sin); + } + if (inet->cmsg_flags) + ip_cmsg_recv(msg, skb); +diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c +index ae03b7b75af6..727678dc7968 100644 +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -176,7 +176,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) + if (IS_ERR(rt)) { + err = PTR_ERR(rt); + if (err == -ENETUNREACH) +- IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); ++ IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); + return err; + } + +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index 0b6136d578f6..7949b5d1663f 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -940,7 +940,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, + err = PTR_ERR(rt); + rt = NULL; + if (err == -ENETUNREACH) +- IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); ++ IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES); + goto out; + } + +@@ -1039,6 +1039,9 @@ int udp_sendpage(struct sock *sk, struct page *page, int offset, + struct udp_sock *up = udp_sk(sk); + int ret; + ++ if (flags & MSG_SENDPAGE_NOTLAST) ++ flags |= MSG_MORE; ++ + if (!up->pending) { + struct msghdr msg = { .msg_flags = flags|MSG_MORE }; + +@@ -1174,14 +1177,8 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, + int is_udplite = IS_UDPLITE(sk); + bool slow; + +- /* +- * Check any passed addresses +- */ +- if (addr_len) +- *addr_len = sizeof(*sin); +- + if (flags & MSG_ERRQUEUE) +- return ip_recv_error(sk, msg, len); ++ return ip_recv_error(sk, msg, len, addr_len); + + try_again: + skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0), +@@ -1234,6 +1231,7 @@ try_again: + sin->sin_port = udp_hdr(skb)->source; + sin->sin_addr.s_addr = ip_hdr(skb)->saddr; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); ++ *addr_len = sizeof(*sin); + } + if (inet->cmsg_flags) + ip_cmsg_recv(msg, skb); +diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c +index 76832c8dc89d..94e5258f3560 100644 +--- a/net/ipv6/datagram.c ++++ b/net/ipv6/datagram.c +@@ -315,7 +315,7 @@ void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu) + /* + * Handle MSG_ERRQUEUE + */ +-int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len) ++int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) + { + struct ipv6_pinfo *np = inet6_sk(sk); + struct sock_exterr_skb *serr; +@@ -366,6 +366,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len) + ipv6_addr_set_v4mapped(*(__be32 *)(nh + serr->addr_offset), + &sin->sin6_addr); + } ++ *addr_len = sizeof(*sin); + } + + memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); +@@ -374,6 +375,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len) + if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) { + sin->sin6_family = AF_INET6; + sin->sin6_flowinfo = 0; ++ sin->sin6_port = 0; + sin->sin6_scope_id = 0; + if (skb->protocol == htons(ETH_P_IPV6)) { + sin->sin6_addr = ipv6_hdr(skb)->saddr; +@@ -418,7 +420,8 @@ out: + /* + * Handle IPV6_RECVPATHMTU + */ +-int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len) ++int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len, ++ int *addr_len) + { + struct ipv6_pinfo *np = inet6_sk(sk); + struct sk_buff *skb; +@@ -452,6 +455,7 @@ int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len) + sin->sin6_port = 0; + sin->sin6_scope_id = mtu_info.ip6m_addr.sin6_scope_id; + sin->sin6_addr = mtu_info.ip6m_addr.sin6_addr; ++ *addr_len = sizeof(*sin); + } + + put_cmsg(msg, SOL_IPV6, IPV6_PATHMTU, sizeof(mtu_info), &mtu_info); +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index 7dabea3a7125..91cd5f1657b7 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -144,8 +144,8 @@ static int ip6_finish_output2(struct sk_buff *skb) + return res; + } + rcu_read_unlock(); +- IP6_INC_STATS_BH(dev_net(dst->dev), +- ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); ++ IP6_INC_STATS(dev_net(dst->dev), ++ ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); + kfree_skb(skb); + return -EINVAL; + } +diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c +index 3ee28700de4c..d6820d019b2b 100644 +--- a/net/ipv6/raw.c ++++ b/net/ipv6/raw.c +@@ -457,14 +457,11 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, + if (flags & MSG_OOB) + return -EOPNOTSUPP; + +- if (addr_len) +- *addr_len=sizeof(*sin6); +- + if (flags & MSG_ERRQUEUE) +- return ipv6_recv_error(sk, msg, len); ++ return ipv6_recv_error(sk, msg, len, addr_len); + + if (np->rxpmtu && np->rxopt.bits.rxpmtu) +- return ipv6_recv_rxpmtu(sk, msg, len); ++ return ipv6_recv_rxpmtu(sk, msg, len, addr_len); + + skb = skb_recv_datagram(sk, flags, noblock, &err); + if (!skb) +@@ -499,6 +496,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, + sin6->sin6_scope_id = 0; + if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) + sin6->sin6_scope_id = IP6CB(skb)->iif; ++ *addr_len = sizeof(*sin6); + } + + sock_recv_ts_and_drops(msg, sk, skb); +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c +index f79bfdbc247f..98fd7384c446 100644 +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -348,14 +348,11 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, + int is_udp4; + bool slow; + +- if (addr_len) +- *addr_len=sizeof(struct sockaddr_in6); +- + if (flags & MSG_ERRQUEUE) +- return ipv6_recv_error(sk, msg, len); ++ return ipv6_recv_error(sk, msg, len, addr_len); + + if (np->rxpmtu && np->rxopt.bits.rxpmtu) +- return ipv6_recv_rxpmtu(sk, msg, len); ++ return ipv6_recv_rxpmtu(sk, msg, len, addr_len); + + try_again: + skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0), +@@ -423,7 +420,7 @@ try_again: + if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) + sin6->sin6_scope_id = IP6CB(skb)->iif; + } +- ++ *addr_len = sizeof(*sin6); + } + if (is_udp4) { + if (inet->cmsg_flags) +diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c +index 9680226640ef..8c06a5065772 100644 +--- a/net/ipx/af_ipx.c ++++ b/net/ipx/af_ipx.c +@@ -1835,8 +1835,6 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, + if (skb->tstamp.tv64) + sk->sk_stamp = skb->tstamp; + +- msg->msg_namelen = sizeof(*sipx); +- + if (sipx) { + sipx->sipx_family = AF_IPX; + sipx->sipx_port = ipx->ipx_source.sock; +@@ -1844,6 +1842,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, + sipx->sipx_network = IPX_SKB_CB(skb)->ipx_source_net; + sipx->sipx_type = ipx->ipx_type; + sipx->sipx_zero = 0; ++ msg->msg_namelen = sizeof(*sipx); + } + rc = copied; + +diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c +index bd25678b1d50..12218f705315 100644 +--- a/net/irda/af_irda.c ++++ b/net/irda/af_irda.c +@@ -1386,8 +1386,6 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock, + + IRDA_DEBUG(4, "%s()\n", __func__); + +- msg->msg_namelen = 0; +- + skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, + flags & MSG_DONTWAIT, &err); + if (!skb) +@@ -1452,8 +1450,6 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, + target = sock_rcvlowat(sk, flags & MSG_WAITALL, size); + timeo = sock_rcvtimeo(sk, noblock); + +- msg->msg_namelen = 0; +- + do { + int chunk; + struct sk_buff *skb = skb_dequeue(&sk->sk_receive_queue); +diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c +index 625bc50391cc..cd6f7a991d80 100644 +--- a/net/iucv/af_iucv.c ++++ b/net/iucv/af_iucv.c +@@ -1331,8 +1331,6 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, + struct sk_buff *skb, *rskb, *cskb; + int err = 0; + +- msg->msg_namelen = 0; +- + if ((sk->sk_state == IUCV_DISCONN) && + skb_queue_empty(&iucv->backlog_skb_q) && + skb_queue_empty(&sk->sk_receive_queue) && +diff --git a/net/key/af_key.c b/net/key/af_key.c +index 2f3ce93d3fc1..d5cd43920ccb 100644 +--- a/net/key/af_key.c ++++ b/net/key/af_key.c +@@ -3595,7 +3595,6 @@ static int pfkey_recvmsg(struct kiocb *kiocb, + if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT)) + goto out; + +- msg->msg_namelen = 0; + skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &err); + if (skb == NULL) + goto out; +diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c +index b1d4370c8962..ea247600f7d9 100644 +--- a/net/l2tp/l2tp_ip.c ++++ b/net/l2tp/l2tp_ip.c +@@ -569,9 +569,6 @@ static int l2tp_ip_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m + if (flags & MSG_OOB) + goto out; + +- if (addr_len) +- *addr_len = sizeof(*sin); +- + skb = skb_recv_datagram(sk, flags, noblock, &err); + if (!skb) + goto out; +@@ -594,6 +591,7 @@ static int l2tp_ip_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m + sin->sin_addr.s_addr = ip_hdr(skb)->saddr; + sin->sin_port = 0; + memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); ++ *addr_len = sizeof(*sin); + } + if (inet->cmsg_flags) + ip_cmsg_recv(msg, skb); +diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c +index 904bc098790d..22112754ba06 100644 +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -200,8 +200,6 @@ static int pppol2tp_recvmsg(struct kiocb *iocb, struct socket *sock, + if (sk->sk_state & PPPOX_BOUND) + goto end; + +- msg->msg_namelen = 0; +- + err = 0; + skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, + flags & MSG_DONTWAIT, &err); +diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c +index e4d2fbb59a7e..df08d7779e1d 100644 +--- a/net/llc/af_llc.c ++++ b/net/llc/af_llc.c +@@ -721,8 +721,6 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, + int target; /* Read at least this many bytes */ + long timeo; + +- msg->msg_namelen = 0; +- + lock_sock(sk); + copied = -ENOTCONN; + if (unlikely(sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN)) +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index 9017e3ef8fee..ff960b792ee4 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -1443,8 +1443,6 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, + } + #endif + +- msg->msg_namelen = 0; +- + copied = data_skb->len; + if (len < copied) { + msg->msg_flags |= MSG_TRUNC; +diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c +index 7ed9b1d0c102..dcf6791ec76d 100644 +--- a/net/netrom/af_netrom.c ++++ b/net/netrom/af_netrom.c +@@ -1181,10 +1181,9 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock, + sax->sax25_family = AF_NETROM; + skb_copy_from_linear_data_offset(skb, 7, sax->sax25_call.ax25_call, + AX25_ADDR_LEN); ++ msg->msg_namelen = sizeof(*sax); + } + +- msg->msg_namelen = sizeof(*sax); +- + skb_free_datagram(sk, skb); + + release_sock(sk); +diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c +index e879dce52818..44835ceb5562 100644 +--- a/net/nfc/rawsock.c ++++ b/net/nfc/rawsock.c +@@ -235,8 +235,6 @@ static int rawsock_recvmsg(struct kiocb *iocb, struct socket *sock, + if (!skb) + return rc; + +- msg->msg_namelen = 0; +- + copied = skb->len; + if (len < copied) { + msg->msg_flags |= MSG_TRUNC; +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 8ed5d9302e88..dbe1715c629f 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -294,6 +294,7 @@ struct packet_sock { + unsigned int tp_reserve; + unsigned int tp_loss:1; + unsigned int tp_tstamp; ++ struct net_device __rcu *cached_dev; + struct packet_type prot_hook ____cacheline_aligned_in_smp; + }; + +@@ -349,11 +350,15 @@ static void __fanout_link(struct sock *sk, struct packet_sock *po); + static void register_prot_hook(struct sock *sk) + { + struct packet_sock *po = pkt_sk(sk); ++ + if (!po->running) { +- if (po->fanout) ++ if (po->fanout) { + __fanout_link(sk, po); +- else ++ } else { + dev_add_pack(&po->prot_hook); ++ rcu_assign_pointer(po->cached_dev, po->prot_hook.dev); ++ } ++ + sock_hold(sk); + po->running = 1; + } +@@ -371,10 +376,13 @@ static void __unregister_prot_hook(struct sock *sk, bool sync) + struct packet_sock *po = pkt_sk(sk); + + po->running = 0; +- if (po->fanout) ++ if (po->fanout) { + __fanout_unlink(sk, po); +- else ++ } else { + __dev_remove_pack(&po->prot_hook); ++ RCU_INIT_POINTER(po->cached_dev, NULL); ++ } ++ + __sock_put(sk); + + if (sync) { +@@ -496,9 +504,9 @@ static void prb_shutdown_retire_blk_timer(struct packet_sock *po, + + pkc = tx_ring ? &po->tx_ring.prb_bdqc : &po->rx_ring.prb_bdqc; + +- spin_lock(&rb_queue->lock); ++ spin_lock_bh(&rb_queue->lock); + pkc->delete_blk_timer = 1; +- spin_unlock(&rb_queue->lock); ++ spin_unlock_bh(&rb_queue->lock); + + prb_del_retire_blk_timer(pkc); + } +@@ -2044,12 +2052,24 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, + return tp_len; + } + ++static struct net_device *packet_cached_dev_get(struct packet_sock *po) ++{ ++ struct net_device *dev; ++ ++ rcu_read_lock(); ++ dev = rcu_dereference(po->cached_dev); ++ if (dev) ++ dev_hold(dev); ++ rcu_read_unlock(); ++ ++ return dev; ++} ++ + static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) + { + struct sk_buff *skb; + struct net_device *dev; + __be16 proto; +- bool need_rls_dev = false; + int err, reserve = 0; + void *ph; + struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name; +@@ -2063,7 +2083,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) + + err = -EBUSY; + if (saddr == NULL) { +- dev = po->prot_hook.dev; ++ dev = packet_cached_dev_get(po); + proto = po->num; + addr = NULL; + } else { +@@ -2077,19 +2097,17 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) + proto = saddr->sll_protocol; + addr = saddr->sll_addr; + dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex); +- need_rls_dev = true; + } + + err = -ENXIO; + if (unlikely(dev == NULL)) + goto out; +- +- reserve = dev->hard_header_len; +- + err = -ENETDOWN; + if (unlikely(!(dev->flags & IFF_UP))) + goto out_put; + ++ reserve = dev->hard_header_len; ++ + size_max = po->tx_ring.frame_size + - (po->tp_hdrlen - sizeof(struct sockaddr_ll)); + +@@ -2166,8 +2184,7 @@ out_status: + __packet_set_status(po, ph, status); + kfree_skb(skb); + out_put: +- if (need_rls_dev) +- dev_put(dev); ++ dev_put(dev); + out: + mutex_unlock(&po->pg_vec_lock); + return err; +@@ -2205,7 +2222,6 @@ static int packet_snd(struct socket *sock, + struct sk_buff *skb; + struct net_device *dev; + __be16 proto; +- bool need_rls_dev = false; + unsigned char *addr; + int err, reserve = 0; + struct virtio_net_hdr vnet_hdr = { 0 }; +@@ -2221,7 +2237,7 @@ static int packet_snd(struct socket *sock, + */ + + if (saddr == NULL) { +- dev = po->prot_hook.dev; ++ dev = packet_cached_dev_get(po); + proto = po->num; + addr = NULL; + } else { +@@ -2233,19 +2249,17 @@ static int packet_snd(struct socket *sock, + proto = saddr->sll_protocol; + addr = saddr->sll_addr; + dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex); +- need_rls_dev = true; + } + + err = -ENXIO; +- if (dev == NULL) ++ if (unlikely(dev == NULL)) + goto out_unlock; +- if (sock->type == SOCK_RAW) +- reserve = dev->hard_header_len; +- + err = -ENETDOWN; +- if (!(dev->flags & IFF_UP)) ++ if (unlikely(!(dev->flags & IFF_UP))) + goto out_unlock; + ++ if (sock->type == SOCK_RAW) ++ reserve = dev->hard_header_len; + if (po->has_vnet_hdr) { + vnet_hdr_len = sizeof(vnet_hdr); + +@@ -2378,15 +2392,14 @@ static int packet_snd(struct socket *sock, + if (err > 0 && (err = net_xmit_errno(err)) != 0) + goto out_unlock; + +- if (need_rls_dev) +- dev_put(dev); ++ dev_put(dev); + + return len; + + out_free: + kfree_skb(skb); + out_unlock: +- if (dev && need_rls_dev) ++ if (dev) + dev_put(dev); + out: + return err; +@@ -2603,6 +2616,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol, + po = pkt_sk(sk); + sk->sk_family = PF_PACKET; + po->num = proto; ++ RCU_INIT_POINTER(po->cached_dev, NULL); + + sk->sk_destruct = packet_sock_destruct; + sk_refcnt_debug_inc(sk); +@@ -2691,7 +2705,6 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, + struct sock *sk = sock->sk; + struct sk_buff *skb; + int copied, err; +- struct sockaddr_ll *sll; + int vnet_hdr_len = 0; + + err = -EINVAL; +@@ -2774,22 +2787,10 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, + goto out_free; + } + +- /* +- * If the address length field is there to be filled in, we fill +- * it in now. ++ /* You lose any data beyond the buffer you gave. If it worries ++ * a user program they can ask the device for its MTU ++ * anyway. + */ +- +- sll = &PACKET_SKB_CB(skb)->sa.ll; +- if (sock->type == SOCK_PACKET) +- msg->msg_namelen = sizeof(struct sockaddr_pkt); +- else +- msg->msg_namelen = sll->sll_halen + offsetof(struct sockaddr_ll, sll_addr); +- +- /* +- * You lose any data beyond the buffer you gave. If it worries a +- * user program they can ask the device for its MTU anyway. +- */ +- + copied = skb->len; + if (copied > len) { + copied = len; +@@ -2802,9 +2803,20 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, + + sock_recv_ts_and_drops(msg, sk, skb); + +- if (msg->msg_name) ++ if (msg->msg_name) { ++ /* If the address length field is there to be filled ++ * in, we fill it in now. ++ */ ++ if (sock->type == SOCK_PACKET) { ++ msg->msg_namelen = sizeof(struct sockaddr_pkt); ++ } else { ++ struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll; ++ msg->msg_namelen = sll->sll_halen + ++ offsetof(struct sockaddr_ll, sll_addr); ++ } + memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa, + msg->msg_namelen); ++ } + + if (pkt_sk(sk)->auxdata) { + struct tpacket_auxdata aux; +diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c +index bf35b4e1a14c..b25f2d321e05 100644 +--- a/net/phonet/datagram.c ++++ b/net/phonet/datagram.c +@@ -139,9 +139,6 @@ static int pn_recvmsg(struct kiocb *iocb, struct sock *sk, + MSG_CMSG_COMPAT)) + goto out_nofree; + +- if (addr_len) +- *addr_len = sizeof(sa); +- + skb = skb_recv_datagram(sk, flags, noblock, &rval); + if (skb == NULL) + goto out_nofree; +@@ -162,8 +159,10 @@ static int pn_recvmsg(struct kiocb *iocb, struct sock *sk, + + rval = (flags & MSG_TRUNC) ? skb->len : copylen; + +- if (msg->msg_name != NULL) +- memcpy(msg->msg_name, &sa, sizeof(struct sockaddr_pn)); ++ if (msg->msg_name != NULL) { ++ memcpy(msg->msg_name, &sa, sizeof(sa)); ++ *addr_len = sizeof(sa); ++ } + + out: + skb_free_datagram(sk, skb); +diff --git a/net/rds/recv.c b/net/rds/recv.c +index 9f0f17cf6bf9..de339b24ca14 100644 +--- a/net/rds/recv.c ++++ b/net/rds/recv.c +@@ -410,8 +410,6 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, + + rdsdebug("size %zu flags 0x%x timeo %ld\n", size, msg_flags, timeo); + +- msg->msg_namelen = 0; +- + if (msg_flags & MSG_OOB) + goto out; + +diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c +index 7f645d115795..ce5f5b934ea1 100644 +--- a/net/rose/af_rose.c ++++ b/net/rose/af_rose.c +@@ -1220,7 +1220,6 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock, + { + struct sock *sk = sock->sk; + struct rose_sock *rose = rose_sk(sk); +- struct sockaddr_rose *srose = (struct sockaddr_rose *)msg->msg_name; + size_t copied; + unsigned char *asmptr; + struct sk_buff *skb; +@@ -1256,8 +1255,11 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock, + + skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); + +- if (srose != NULL) { +- memset(srose, 0, msg->msg_namelen); ++ if (msg->msg_name) { ++ struct sockaddr_rose *srose; ++ ++ memset(msg->msg_name, 0, sizeof(struct full_sockaddr_rose)); ++ srose = msg->msg_name; + srose->srose_family = AF_ROSE; + srose->srose_addr = rose->dest_addr; + srose->srose_call = rose->dest_call; +diff --git a/net/rxrpc/ar-recvmsg.c b/net/rxrpc/ar-recvmsg.c +index 4b48687c3890..898492a8d61b 100644 +--- a/net/rxrpc/ar-recvmsg.c ++++ b/net/rxrpc/ar-recvmsg.c +@@ -143,10 +143,13 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock, + + /* copy the peer address and timestamp */ + if (!continue_call) { +- if (msg->msg_name && msg->msg_namelen > 0) ++ if (msg->msg_name) { ++ size_t len = ++ sizeof(call->conn->trans->peer->srx); + memcpy(msg->msg_name, +- &call->conn->trans->peer->srx, +- sizeof(call->conn->trans->peer->srx)); ++ &call->conn->trans->peer->srx, len); ++ msg->msg_namelen = len; ++ } + sock_recv_ts_and_drops(msg, &rx->sk, skb); + } + +diff --git a/net/socket.c b/net/socket.c +index acc769562707..4006452e8475 100644 +--- a/net/socket.c ++++ b/net/socket.c +@@ -215,12 +215,13 @@ static int move_addr_to_user(struct sockaddr_storage *kaddr, int klen, + int err; + int len; + ++ BUG_ON(klen > sizeof(struct sockaddr_storage)); + err = get_user(len, ulen); + if (err) + return err; + if (len > klen) + len = klen; +- if (len < 0 || len > sizeof(struct sockaddr_storage)) ++ if (len < 0) + return -EINVAL; + if (len) { + if (audit_sockaddr(klen, kaddr)) +@@ -1775,8 +1776,10 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size, + msg.msg_iov = &iov; + iov.iov_len = size; + iov.iov_base = ubuf; +- msg.msg_name = (struct sockaddr *)&address; +- msg.msg_namelen = sizeof(address); ++ /* Save some cycles and don't copy the address if not needed */ ++ msg.msg_name = addr ? (struct sockaddr *)&address : NULL; ++ /* We assume all kernel code knows the size of sockaddr_storage */ ++ msg.msg_namelen = 0; + if (sock->file->f_flags & O_NONBLOCK) + flags |= MSG_DONTWAIT; + err = sock_recvmsg(sock, &msg, size, flags); +@@ -1905,7 +1908,7 @@ static int copy_msghdr_from_user(struct msghdr *kmsg, + if (copy_from_user(kmsg, umsg, sizeof(struct msghdr))) + return -EFAULT; + if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) +- return -EINVAL; ++ kmsg->msg_namelen = sizeof(struct sockaddr_storage); + return 0; + } + +@@ -2161,16 +2164,14 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, + goto out; + } + +- /* +- * Save the user-mode address (verify_iovec will change the +- * kernel msghdr to use the kernel address space) ++ /* Save the user-mode address (verify_iovec will change the ++ * kernel msghdr to use the kernel address space) + */ +- + uaddr = (__force void __user *)msg_sys->msg_name; + uaddr_len = COMPAT_NAMELEN(msg); +- if (MSG_CMSG_COMPAT & flags) { ++ if (MSG_CMSG_COMPAT & flags) + err = verify_compat_iovec(msg_sys, iov, &addr, VERIFY_WRITE); +- } else ++ else + err = verify_iovec(msg_sys, iov, &addr, VERIFY_WRITE); + if (err < 0) + goto out_freeiov; +@@ -2179,6 +2180,9 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, + cmsg_ptr = (unsigned long)msg_sys->msg_control; + msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT); + ++ /* We assume all kernel code knows the size of sockaddr_storage */ ++ msg_sys->msg_namelen = 0; ++ + if (sock->file->f_flags & O_NONBLOCK) + flags |= MSG_DONTWAIT; + err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys, +diff --git a/net/tipc/socket.c b/net/tipc/socket.c +index 1441ab70b98c..64b847008ee3 100644 +--- a/net/tipc/socket.c ++++ b/net/tipc/socket.c +@@ -949,9 +949,6 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock, + goto exit; + } + +- /* will be updated in set_orig_addr() if needed */ +- m->msg_namelen = 0; +- + timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); + restart: + +@@ -1078,9 +1075,6 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock, + goto exit; + } + +- /* will be updated in set_orig_addr() if needed */ +- m->msg_namelen = 0; +- + target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); + timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); + restart: +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index ed005b425a7c..0540dd9b0387 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -1755,7 +1755,6 @@ static void unix_copy_addr(struct msghdr *msg, struct sock *sk) + { + struct unix_sock *u = unix_sk(sk); + +- msg->msg_namelen = 0; + if (u->addr) { + msg->msg_namelen = u->addr->len; + memcpy(msg->msg_name, u->addr->name, u->addr->len); +@@ -1779,8 +1778,6 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, + if (flags&MSG_OOB) + goto out; + +- msg->msg_namelen = 0; +- + err = mutex_lock_interruptible(&u->readlock); + if (err) { + err = sock_intr_errno(sock_rcvtimeo(sk, noblock)); +@@ -1922,8 +1919,6 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, + target = sock_rcvlowat(sk, flags&MSG_WAITALL, size); + timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT); + +- msg->msg_namelen = 0; +- + /* Lock the socket to prevent queue disordering + * while sleeps in memcpy_tomsg + */ +diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c +index b943e3e71bd2..92aed9e45c73 100644 +--- a/net/x25/af_x25.c ++++ b/net/x25/af_x25.c +@@ -1343,10 +1343,9 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock, + if (sx25) { + sx25->sx25_family = AF_X25; + sx25->sx25_addr = x25->dest_addr; ++ msg->msg_namelen = sizeof(*sx25); + } + +- msg->msg_namelen = sizeof(struct sockaddr_x25); +- + x25_check_rbuf(sk); + rc = copied; + out_free_dgram: diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.73-74.patch b/patch/kernel/sun8i-default/0001-patch-3.4.73-74.patch new file mode 100644 index 000000000..3d0c13e74 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.73-74.patch @@ -0,0 +1,602 @@ +diff --git a/Documentation/i2c/busses/i2c-i801 b/Documentation/i2c/busses/i2c-i801 +index 99d4e442b77d..8bb57d7c12ea 100644 +--- a/Documentation/i2c/busses/i2c-i801 ++++ b/Documentation/i2c/busses/i2c-i801 +@@ -22,6 +22,7 @@ Supported adapters: + * Intel Panther Point (PCH) + * Intel Lynx Point (PCH) + * Intel Lynx Point-LP (PCH) ++ * Intel Avoton (SOC) + Datasheets: Publicly available at the Intel website + + On Intel Patsburg and later chipsets, both the normal host SMBus controller +diff --git a/Makefile b/Makefile +index 2ea579016292..ce277ff0fd72 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 73 ++SUBLEVEL = 74 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c +index 425162e22af5..2f53b892fd80 100644 +--- a/arch/um/os-Linux/start_up.c ++++ b/arch/um/os-Linux/start_up.c +@@ -15,6 +15,8 @@ + #include + #include + #include ++#include ++#include + #include + #include "init.h" + #include "os.h" +diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c +index 850246206b12..585c3b279feb 100644 +--- a/crypto/algif_hash.c ++++ b/crypto/algif_hash.c +@@ -117,6 +117,9 @@ static ssize_t hash_sendpage(struct socket *sock, struct page *page, + if (flags & MSG_SENDPAGE_NOTLAST) + flags |= MSG_MORE; + ++ if (flags & MSG_SENDPAGE_NOTLAST) ++ flags |= MSG_MORE; ++ + lock_sock(sk); + sg_init_table(ctx->sgl.sg, 1); + sg_set_page(ctx->sgl.sg, page, size, offset); +diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c +index a19c027b29bd..918a3b4148b8 100644 +--- a/crypto/algif_skcipher.c ++++ b/crypto/algif_skcipher.c +@@ -381,6 +381,9 @@ static ssize_t skcipher_sendpage(struct socket *sock, struct page *page, + if (flags & MSG_SENDPAGE_NOTLAST) + flags |= MSG_MORE; + ++ if (flags & MSG_SENDPAGE_NOTLAST) ++ flags |= MSG_MORE; ++ + lock_sock(sk); + if (!ctx->more && ctx->used) + goto unlock; +diff --git a/crypto/authenc.c b/crypto/authenc.c +index 5ef7ba6b6a76..d21da2f0f508 100644 +--- a/crypto/authenc.c ++++ b/crypto/authenc.c +@@ -368,9 +368,10 @@ static void crypto_authenc_encrypt_done(struct crypto_async_request *req, + if (!err) { + struct crypto_aead *authenc = crypto_aead_reqtfm(areq); + struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); +- struct ablkcipher_request *abreq = aead_request_ctx(areq); +- u8 *iv = (u8 *)(abreq + 1) + +- crypto_ablkcipher_reqsize(ctx->enc); ++ struct authenc_request_ctx *areq_ctx = aead_request_ctx(areq); ++ struct ablkcipher_request *abreq = (void *)(areq_ctx->tail ++ + ctx->reqoff); ++ u8 *iv = (u8 *)abreq - crypto_ablkcipher_ivsize(ctx->enc); + + err = crypto_authenc_genicv(areq, iv, 0); + } +diff --git a/crypto/ccm.c b/crypto/ccm.c +index 32fe1bb5decb..18d64ad0433c 100644 +--- a/crypto/ccm.c ++++ b/crypto/ccm.c +@@ -271,7 +271,8 @@ static int crypto_ccm_auth(struct aead_request *req, struct scatterlist *plain, + } + + /* compute plaintext into mac */ +- get_data_to_compute(cipher, pctx, plain, cryptlen); ++ if (cryptlen) ++ get_data_to_compute(cipher, pctx, plain, cryptlen); + + out: + return err; +diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c +index 60662545cd14..c20f1578d393 100644 +--- a/drivers/ata/ahci.c ++++ b/drivers/ata/ahci.c +@@ -268,6 +268,30 @@ static const struct pci_device_id ahci_pci_tbl[] = { + { PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point RAID */ + { PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */ + { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point RAID */ ++ { PCI_VDEVICE(INTEL, 0x9c02), board_ahci }, /* Lynx Point-LP AHCI */ ++ { PCI_VDEVICE(INTEL, 0x9c03), board_ahci }, /* Lynx Point-LP AHCI */ ++ { PCI_VDEVICE(INTEL, 0x9c04), board_ahci }, /* Lynx Point-LP RAID */ ++ { PCI_VDEVICE(INTEL, 0x9c05), board_ahci }, /* Lynx Point-LP RAID */ ++ { PCI_VDEVICE(INTEL, 0x9c06), board_ahci }, /* Lynx Point-LP RAID */ ++ { PCI_VDEVICE(INTEL, 0x9c07), board_ahci }, /* Lynx Point-LP RAID */ ++ { PCI_VDEVICE(INTEL, 0x9c0e), board_ahci }, /* Lynx Point-LP RAID */ ++ { PCI_VDEVICE(INTEL, 0x9c0f), board_ahci }, /* Lynx Point-LP RAID */ ++ { PCI_VDEVICE(INTEL, 0x1f22), board_ahci }, /* Avoton AHCI */ ++ { PCI_VDEVICE(INTEL, 0x1f23), board_ahci }, /* Avoton AHCI */ ++ { PCI_VDEVICE(INTEL, 0x1f24), board_ahci }, /* Avoton RAID */ ++ { PCI_VDEVICE(INTEL, 0x1f25), board_ahci }, /* Avoton RAID */ ++ { PCI_VDEVICE(INTEL, 0x1f26), board_ahci }, /* Avoton RAID */ ++ { PCI_VDEVICE(INTEL, 0x1f27), board_ahci }, /* Avoton RAID */ ++ { PCI_VDEVICE(INTEL, 0x1f2e), board_ahci }, /* Avoton RAID */ ++ { PCI_VDEVICE(INTEL, 0x1f2f), board_ahci }, /* Avoton RAID */ ++ { PCI_VDEVICE(INTEL, 0x1f32), board_ahci }, /* Avoton AHCI */ ++ { PCI_VDEVICE(INTEL, 0x1f33), board_ahci }, /* Avoton AHCI */ ++ { PCI_VDEVICE(INTEL, 0x1f34), board_ahci }, /* Avoton RAID */ ++ { PCI_VDEVICE(INTEL, 0x1f35), board_ahci }, /* Avoton RAID */ ++ { PCI_VDEVICE(INTEL, 0x1f36), board_ahci }, /* Avoton RAID */ ++ { PCI_VDEVICE(INTEL, 0x1f37), board_ahci }, /* Avoton RAID */ ++ { PCI_VDEVICE(INTEL, 0x1f3e), board_ahci }, /* Avoton RAID */ ++ { PCI_VDEVICE(INTEL, 0x1f3f), board_ahci }, /* Avoton RAID */ + + /* JMicron 360/1/3/5/6, match class to avoid IDE function */ + { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, +diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c +index 40cc0cf2ded6..e6939e13e338 100644 +--- a/drivers/char/i8k.c ++++ b/drivers/char/i8k.c +@@ -664,6 +664,13 @@ static struct dmi_system_id __initdata i8k_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "Vostro"), + }, + }, ++ { ++ .ident = "Dell XPS421", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "XPS L421X"), ++ }, ++ }, + { } + }; + +diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c +index 5a1817eedd1b..c81b8da669ea 100644 +--- a/drivers/gpio/gpio-mpc8xxx.c ++++ b/drivers/gpio/gpio-mpc8xxx.c +@@ -69,10 +69,14 @@ static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio) + u32 val; + struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); + struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); ++ u32 out_mask, out_shadow; + +- val = in_be32(mm->regs + GPIO_DAT) & ~in_be32(mm->regs + GPIO_DIR); ++ out_mask = in_be32(mm->regs + GPIO_DIR); + +- return (val | mpc8xxx_gc->data) & mpc8xxx_gpio2mask(gpio); ++ val = in_be32(mm->regs + GPIO_DAT) & ~out_mask; ++ out_shadow = mpc8xxx_gc->data & out_mask; ++ ++ return (val | out_shadow) & mpc8xxx_gpio2mask(gpio); + } + + static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio) +diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig +index ea8736bc257d..bc625f6c5b4c 100644 +--- a/drivers/i2c/busses/Kconfig ++++ b/drivers/i2c/busses/Kconfig +@@ -105,6 +105,7 @@ config I2C_I801 + Panther Point (PCH) + Lynx Point (PCH) + Lynx Point-LP (PCH) ++ Avoton (SOC) + + This driver can also be built as a module. If so, the module + will be called i2c-i801. +diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c +index d88ec812160e..d63e130690e9 100644 +--- a/drivers/i2c/busses/i2c-i801.c ++++ b/drivers/i2c/busses/i2c-i801.c +@@ -53,6 +53,7 @@ + Panther Point (PCH) 0x1e22 32 hard yes yes yes + Lynx Point (PCH) 0x8c22 32 hard yes yes yes + Lynx Point-LP (PCH) 0x9c22 32 hard yes yes yes ++ Avoton (SOC) 0x1f3c 32 hard yes yes yes + + Features supported by this driver: + Software PEC no +@@ -145,6 +146,7 @@ + #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1 0x1d71 + #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2 0x1d72 + #define PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS 0x1e22 ++#define PCI_DEVICE_ID_INTEL_AVOTON_SMBUS 0x1f3c + #define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330 + #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30 + #define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22 +@@ -639,6 +641,7 @@ static DEFINE_PCI_DEVICE_TABLE(i801_ids) = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS) }, ++ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_AVOTON_SMBUS) }, + { 0, } + }; + +diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig +index 332597980817..20026e3a234a 100644 +--- a/drivers/input/Kconfig ++++ b/drivers/input/Kconfig +@@ -71,7 +71,7 @@ config INPUT_SPARSEKMAP + comment "Userland interfaces" + + config INPUT_MOUSEDEV +- tristate "Mouse interface" if EXPERT ++ tristate "Mouse interface" + default y + help + Say Y here if you want your mouse to be accessible as char devices +diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig +index f354813a13e8..69a45701d94a 100644 +--- a/drivers/input/keyboard/Kconfig ++++ b/drivers/input/keyboard/Kconfig +@@ -2,7 +2,7 @@ + # Input core configuration + # + menuconfig INPUT_KEYBOARD +- bool "Keyboards" if EXPERT || !X86 ++ bool "Keyboards" + default y + help + Say Y here, and a list of supported keyboards will be displayed. +@@ -67,7 +67,7 @@ config KEYBOARD_ATARI + module will be called atakbd. + + config KEYBOARD_ATKBD +- tristate "AT keyboard" if EXPERT || !X86 ++ tristate "AT keyboard" + default y + select SERIO + select SERIO_LIBPS2 +diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig +index 55f2c2293ec6..93d4182a8916 100644 +--- a/drivers/input/serio/Kconfig ++++ b/drivers/input/serio/Kconfig +@@ -2,7 +2,7 @@ + # Input core configuration + # + config SERIO +- tristate "Serial I/O support" if EXPERT || !X86 ++ tristate "Serial I/O support" + default y + help + Say Yes here if you have any input device that uses serial I/O to +@@ -19,7 +19,7 @@ config SERIO + if SERIO + + config SERIO_I8042 +- tristate "i8042 PC Keyboard controller" if EXPERT || !X86 ++ tristate "i8042 PC Keyboard controller" + default y + depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && \ + (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN +@@ -168,7 +168,7 @@ config SERIO_MACEPS2 + module will be called maceps2. + + config SERIO_LIBPS2 +- tristate "PS/2 driver library" if EXPERT ++ tristate "PS/2 driver library" + depends on SERIO_I8042 || SERIO_I8042=n + help + Say Y here if you are using a driver for device connected +diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c +index 00e5fcac8fdf..cbee842f8b6b 100644 +--- a/drivers/misc/enclosure.c ++++ b/drivers/misc/enclosure.c +@@ -198,6 +198,13 @@ static void enclosure_remove_links(struct enclosure_component *cdev) + { + char name[ENCLOSURE_NAME_SIZE]; + ++ /* ++ * In odd circumstances, like multipath devices, something else may ++ * already have removed the links, so check for this condition first. ++ */ ++ if (!cdev->dev->kobj.sd) ++ return; ++ + enclosure_link_name(cdev, name); + sysfs_remove_link(&cdev->dev->kobj, name); + sysfs_remove_link(&cdev->cdev.kobj, "device"); +diff --git a/drivers/net/ethernet/smsc/smc91x.h b/drivers/net/ethernet/smsc/smc91x.h +index 5f53fbbf67be..ff1af41e4b5d 100644 +--- a/drivers/net/ethernet/smsc/smc91x.h ++++ b/drivers/net/ethernet/smsc/smc91x.h +@@ -46,7 +46,8 @@ + defined(CONFIG_MACH_LITTLETON) ||\ + defined(CONFIG_MACH_ZYLONITE2) ||\ + defined(CONFIG_ARCH_VIPER) ||\ +- defined(CONFIG_MACH_STARGATE2) ++ defined(CONFIG_MACH_STARGATE2) ||\ ++ defined(CONFIG_ARCH_VERSATILE) + + #include + +@@ -154,6 +155,8 @@ static inline void SMC_outw(u16 val, void __iomem *ioaddr, int reg) + #define SMC_outl(v, a, r) writel(v, (a) + (r)) + #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) + #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) ++#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) ++#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) + #define SMC_IRQ_FLAGS (-1) /* from resource */ + + /* We actually can't write halfwords properly if not word aligned */ +@@ -206,23 +209,6 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) + #define RPC_LSA_DEFAULT RPC_LED_TX_RX + #define RPC_LSB_DEFAULT RPC_LED_100_10 + +-#elif defined(CONFIG_ARCH_VERSATILE) +- +-#define SMC_CAN_USE_8BIT 1 +-#define SMC_CAN_USE_16BIT 1 +-#define SMC_CAN_USE_32BIT 1 +-#define SMC_NOWAIT 1 +- +-#define SMC_inb(a, r) readb((a) + (r)) +-#define SMC_inw(a, r) readw((a) + (r)) +-#define SMC_inl(a, r) readl((a) + (r)) +-#define SMC_outb(v, a, r) writeb(v, (a) + (r)) +-#define SMC_outw(v, a, r) writew(v, (a) + (r)) +-#define SMC_outl(v, a, r) writel(v, (a) + (r)) +-#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) +-#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) +-#define SMC_IRQ_FLAGS (-1) /* from resource */ +- + #elif defined(CONFIG_MN10300) + + /* +diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c +index b0fefc435c03..599240af2244 100644 +--- a/drivers/scsi/hpsa.c ++++ b/drivers/scsi/hpsa.c +@@ -1219,7 +1219,7 @@ static void complete_scsi_command(struct CommandList *cp) + "has check condition: aborted command: " + "ASC: 0x%x, ASCQ: 0x%x\n", + cp, asc, ascq); +- cmd->result = DID_SOFT_ERROR << 16; ++ cmd->result |= DID_SOFT_ERROR << 16; + break; + } + /* Must be some other type of check condition */ +@@ -4466,7 +4466,7 @@ reinit_after_soft_reset: + hpsa_hba_inquiry(h); + hpsa_register_scsi(h); /* hook ourselves into SCSI subsystem */ + start_controller_lockup_detector(h); +- return 1; ++ return 0; + + clean4: + hpsa_free_sg_chain_blocks(h); +diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c +index d109cc3a17b6..51ee663c1310 100644 +--- a/drivers/scsi/libsas/sas_ata.c ++++ b/drivers/scsi/libsas/sas_ata.c +@@ -211,7 +211,7 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc) + qc->tf.nsect = 0; + } + +- ata_tf_to_fis(&qc->tf, 1, 0, (u8*)&task->ata_task.fis); ++ ata_tf_to_fis(&qc->tf, qc->dev->link->pmp, 1, (u8 *)&task->ata_task.fis); + task->uldd_task = qc; + if (ata_is_atapi(qc->tf.protocol)) { + memcpy(task->ata_task.atapi_packet, qc->cdb, qc->dev->cdb_len); +diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +index e411f1865298..4a9dd86bce8e 100644 +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -1542,6 +1542,8 @@ static int acm_reset_resume(struct usb_interface *intf) + + static const struct usb_device_id acm_ids[] = { + /* quirky and broken devices */ ++ { USB_DEVICE(0x17ef, 0x7000), /* Lenovo USB modem */ ++ .driver_info = NO_UNION_NORMAL, },/* has no union descriptor */ + { USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */ + .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ + }, +diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c +index 91293b68df5a..8ccbf5e6b549 100644 +--- a/drivers/usb/serial/mos7840.c ++++ b/drivers/usb/serial/mos7840.c +@@ -1962,25 +1962,25 @@ static void mos7840_change_port_settings(struct tty_struct *tty, + iflag = tty->termios->c_iflag; + + /* Change the number of bits */ +- if (cflag & CSIZE) { +- switch (cflag & CSIZE) { +- case CS5: +- lData = LCR_BITS_5; +- break; ++ switch (cflag & CSIZE) { ++ case CS5: ++ lData = LCR_BITS_5; ++ break; + +- case CS6: +- lData = LCR_BITS_6; +- break; ++ case CS6: ++ lData = LCR_BITS_6; ++ break; + +- case CS7: +- lData = LCR_BITS_7; +- break; +- default: +- case CS8: +- lData = LCR_BITS_8; +- break; +- } ++ case CS7: ++ lData = LCR_BITS_7; ++ break; ++ ++ default: ++ case CS8: ++ lData = LCR_BITS_8; ++ break; + } ++ + /* Change the Parity bit */ + if (cflag & PARENB) { + if (cflag & PARODD) { +diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c +index a1a9062954c4..1dcccd43d629 100644 +--- a/drivers/usb/serial/pl2303.c ++++ b/drivers/usb/serial/pl2303.c +@@ -290,24 +290,22 @@ static void pl2303_set_termios(struct tty_struct *tty, + dbg("0xa1:0x21:0:0 %d - %x %x %x %x %x %x %x", i, + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); + +- if (cflag & CSIZE) { +- switch (cflag & CSIZE) { +- case CS5: +- buf[6] = 5; +- break; +- case CS6: +- buf[6] = 6; +- break; +- case CS7: +- buf[6] = 7; +- break; +- default: +- case CS8: +- buf[6] = 8; +- break; +- } +- dbg("%s - data bits = %d", __func__, buf[6]); ++ switch (cflag & CSIZE) { ++ case CS5: ++ buf[6] = 5; ++ break; ++ case CS6: ++ buf[6] = 6; ++ break; ++ case CS7: ++ buf[6] = 7; ++ break; ++ default: ++ case CS8: ++ buf[6] = 8; ++ break; + } ++ dbg("%s - data bits = %d", __func__, buf[6]); + + /* For reference buf[0]:buf[3] baud rate value */ + /* NOTE: Only the values defined in baud_sup are supported ! +diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c +index f06c9a8f3d37..003ef9019ad8 100644 +--- a/drivers/usb/serial/spcp8x5.c ++++ b/drivers/usb/serial/spcp8x5.c +@@ -396,22 +396,20 @@ static void spcp8x5_set_termios(struct tty_struct *tty, + } + + /* Set Data Length : 00:5bit, 01:6bit, 10:7bit, 11:8bit */ +- if (cflag & CSIZE) { +- switch (cflag & CSIZE) { +- case CS5: +- buf[1] |= SET_UART_FORMAT_SIZE_5; +- break; +- case CS6: +- buf[1] |= SET_UART_FORMAT_SIZE_6; +- break; +- case CS7: +- buf[1] |= SET_UART_FORMAT_SIZE_7; +- break; +- default: +- case CS8: +- buf[1] |= SET_UART_FORMAT_SIZE_8; +- break; +- } ++ switch (cflag & CSIZE) { ++ case CS5: ++ buf[1] |= SET_UART_FORMAT_SIZE_5; ++ break; ++ case CS6: ++ buf[1] |= SET_UART_FORMAT_SIZE_6; ++ break; ++ case CS7: ++ buf[1] |= SET_UART_FORMAT_SIZE_7; ++ break; ++ default: ++ case CS8: ++ buf[1] |= SET_UART_FORMAT_SIZE_8; ++ break; + } + + /* Set Stop bit2 : 0:1bit 1:2bit */ +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index cabddb5da071..a7ea637bf215 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -4041,11 +4041,17 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata) + return; + + switch (task->tk_status) { +- case -NFS4ERR_STALE_STATEID: +- case -NFS4ERR_EXPIRED: + case 0: + renew_lease(data->res.server, data->timestamp); + break; ++ case -NFS4ERR_ADMIN_REVOKED: ++ case -NFS4ERR_DELEG_REVOKED: ++ case -NFS4ERR_BAD_STATEID: ++ case -NFS4ERR_OLD_STATEID: ++ case -NFS4ERR_STALE_STATEID: ++ case -NFS4ERR_EXPIRED: ++ task->tk_status = 0; ++ break; + default: + if (nfs4_async_handle_error(task, data->res.server, NULL) == + -EAGAIN) { +diff --git a/kernel/irq/pm.c b/kernel/irq/pm.c +index 15e53b1766a6..dcd3f9796817 100644 +--- a/kernel/irq/pm.c ++++ b/kernel/irq/pm.c +@@ -50,7 +50,7 @@ static void resume_irqs(bool want_early) + bool is_early = desc->action && + desc->action->flags & IRQF_EARLY_RESUME; + +- if (is_early != want_early) ++ if (!is_early && want_early) + continue; + + raw_spin_lock_irqsave(&desc->lock, flags); +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index 7949b5d1663f..19e784237f7a 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -1042,6 +1042,9 @@ int udp_sendpage(struct sock *sk, struct page *page, int offset, + if (flags & MSG_SENDPAGE_NOTLAST) + flags |= MSG_MORE; + ++ if (flags & MSG_SENDPAGE_NOTLAST) ++ flags |= MSG_MORE; ++ + if (!up->pending) { + struct msghdr msg = { .msg_flags = flags|MSG_MORE }; + +diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c +index a32caa72bd7d..8b5afc1d2e60 100644 +--- a/sound/soc/codecs/wm8731.c ++++ b/sound/soc/codecs/wm8731.c +@@ -406,10 +406,10 @@ static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai, + iface |= 0x0001; + break; + case SND_SOC_DAIFMT_DSP_A: +- iface |= 0x0003; ++ iface |= 0x0013; + break; + case SND_SOC_DAIFMT_DSP_B: +- iface |= 0x0013; ++ iface |= 0x0003; + break; + default: + return -EINVAL; +diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c +index 9d242351e6e8..d5ab3351c2bc 100644 +--- a/sound/soc/codecs/wm8990.c ++++ b/sound/soc/codecs/wm8990.c +@@ -1265,6 +1265,8 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec, + + /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ + snd_soc_write(codec, WM8990_ANTIPOP2, 0x0); ++ ++ codec->cache_sync = 1; + break; + } + diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.74-75.patch b/patch/kernel/sun8i-default/0001-patch-3.4.74-75.patch new file mode 100644 index 000000000..9715a36bc --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.74-75.patch @@ -0,0 +1,1099 @@ +diff --git a/Makefile b/Makefile +index ce277ff0fd72..2d084a418789 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 74 ++SUBLEVEL = 75 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c +index 48f36246a5d7..e09e5211bace 100644 +--- a/arch/arm/kernel/process.c ++++ b/arch/arm/kernel/process.c +@@ -503,6 +503,7 @@ EXPORT_SYMBOL(kernel_thread); + unsigned long get_wchan(struct task_struct *p) + { + struct stackframe frame; ++ unsigned long stack_page; + int count = 0; + if (!p || p == current || p->state == TASK_RUNNING) + return 0; +@@ -511,9 +512,11 @@ unsigned long get_wchan(struct task_struct *p) + frame.sp = thread_saved_sp(p); + frame.lr = 0; /* recovered from the stack */ + frame.pc = thread_saved_pc(p); ++ stack_page = (unsigned long)task_stack_page(p); + do { +- int ret = unwind_frame(&frame); +- if (ret < 0) ++ if (frame.sp < stack_page || ++ frame.sp >= stack_page + THREAD_SIZE || ++ unwind_frame(&frame) < 0) + return 0; + if (!in_sched_functions(frame.pc)) + return frame.pc; +diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c +index 00f79e59985b..af4e8c8a5422 100644 +--- a/arch/arm/kernel/stacktrace.c ++++ b/arch/arm/kernel/stacktrace.c +@@ -31,7 +31,7 @@ int notrace unwind_frame(struct stackframe *frame) + high = ALIGN(low, THREAD_SIZE); + + /* check current frame pointer is within bounds */ +- if (fp < (low + 12) || fp + 4 >= high) ++ if (fp < low + 12 || fp > high - 4) + return -EINVAL; + + /* restore the registers from the stack frame */ +diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c +index 7144ae651d3d..bb7ed98ab9af 100644 +--- a/arch/arm/mach-omap2/omap_hwmod.c ++++ b/arch/arm/mach-omap2/omap_hwmod.c +@@ -317,7 +317,7 @@ static int _set_clockactivity(struct omap_hwmod *oh, u8 clockact, u32 *v) + } + + /** +- * _set_softreset: set OCP_SYSCONFIG.CLOCKACTIVITY bits in @v ++ * _set_softreset: set OCP_SYSCONFIG.SOFTRESET bit in @v + * @oh: struct omap_hwmod * + * @v: pointer to register contents to modify + * +@@ -1378,6 +1378,36 @@ static int _read_hardreset(struct omap_hwmod *oh, const char *name) + } + + /** ++ * _clear_softreset: clear OCP_SYSCONFIG.SOFTRESET bit in @v ++ * @oh: struct omap_hwmod * ++ * @v: pointer to register contents to modify ++ * ++ * Clear the SOFTRESET bit in @v for hwmod @oh. Returns -EINVAL upon ++ * error or 0 upon success. ++ */ ++static int _clear_softreset(struct omap_hwmod *oh, u32 *v) ++{ ++ u32 softrst_mask; ++ ++ if (!oh->class->sysc || ++ !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET)) ++ return -EINVAL; ++ ++ if (!oh->class->sysc->sysc_fields) { ++ WARN(1, ++ "omap_hwmod: %s: sysc_fields absent for sysconfig class\n", ++ oh->name); ++ return -EINVAL; ++ } ++ ++ softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift); ++ ++ *v &= ~softrst_mask; ++ ++ return 0; ++} ++ ++/** + * _ocp_softreset - reset an omap_hwmod via the OCP_SYSCONFIG bit + * @oh: struct omap_hwmod * + * +@@ -1420,6 +1450,12 @@ static int _ocp_softreset(struct omap_hwmod *oh) + ret = _set_softreset(oh, &v); + if (ret) + goto dis_opt_clks; ++ ++ _write_sysconfig(v, oh); ++ ret = _clear_softreset(oh, &v); ++ if (ret) ++ goto dis_opt_clks; ++ + _write_sysconfig(v, oh); + + if (oh->class->sysc->srst_udelay) +@@ -1918,6 +1954,11 @@ int omap_hwmod_softreset(struct omap_hwmod *oh) + goto error; + _write_sysconfig(v, oh); + ++ ret = _clear_softreset(oh, &v); ++ if (ret) ++ goto error; ++ _write_sysconfig(v, oh); ++ + error: + return ret; + } +diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +index db86ce90c69f..a875de49aa9c 100644 +--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c ++++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +@@ -3347,7 +3347,8 @@ static struct omap_hwmod_class_sysconfig omap3xxx_usb_host_hs_sysc = { + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP | +- SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), ++ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | ++ SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +@@ -3465,15 +3466,7 @@ static struct omap_hwmod omap3xxx_usb_host_hs_hwmod = { + * hence HWMOD_SWSUP_MSTANDBY + */ + +- /* +- * During system boot; If the hwmod framework resets the module +- * the module will have smart idle settings; which can lead to deadlock +- * (above Errata Id:i660); so, dont reset the module during boot; +- * Use HWMOD_INIT_NO_RESET. +- */ +- +- .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY | +- HWMOD_INIT_NO_RESET, ++ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, + }; + + /* +diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c +index 4d4eb60bad1e..aeb7c10daf56 100644 +--- a/arch/arm/mach-pxa/tosa.c ++++ b/arch/arm/mach-pxa/tosa.c +@@ -424,57 +424,57 @@ static struct platform_device tosa_power_device = { + * Tosa Keyboard + */ + static const uint32_t tosakbd_keymap[] = { +- KEY(0, 2, KEY_W), +- KEY(0, 6, KEY_K), +- KEY(0, 7, KEY_BACKSPACE), +- KEY(0, 8, KEY_P), +- KEY(1, 1, KEY_Q), +- KEY(1, 2, KEY_E), +- KEY(1, 3, KEY_T), +- KEY(1, 4, KEY_Y), +- KEY(1, 6, KEY_O), +- KEY(1, 7, KEY_I), +- KEY(1, 8, KEY_COMMA), +- KEY(2, 1, KEY_A), +- KEY(2, 2, KEY_D), +- KEY(2, 3, KEY_G), +- KEY(2, 4, KEY_U), +- KEY(2, 6, KEY_L), +- KEY(2, 7, KEY_ENTER), +- KEY(2, 8, KEY_DOT), +- KEY(3, 1, KEY_Z), +- KEY(3, 2, KEY_C), +- KEY(3, 3, KEY_V), +- KEY(3, 4, KEY_J), +- KEY(3, 5, TOSA_KEY_ADDRESSBOOK), +- KEY(3, 6, TOSA_KEY_CANCEL), +- KEY(3, 7, TOSA_KEY_CENTER), +- KEY(3, 8, TOSA_KEY_OK), +- KEY(3, 9, KEY_LEFTSHIFT), +- KEY(4, 1, KEY_S), +- KEY(4, 2, KEY_R), +- KEY(4, 3, KEY_B), +- KEY(4, 4, KEY_N), +- KEY(4, 5, TOSA_KEY_CALENDAR), +- KEY(4, 6, TOSA_KEY_HOMEPAGE), +- KEY(4, 7, KEY_LEFTCTRL), +- KEY(4, 8, TOSA_KEY_LIGHT), +- KEY(4, 10, KEY_RIGHTSHIFT), +- KEY(5, 1, KEY_TAB), +- KEY(5, 2, KEY_SLASH), +- KEY(5, 3, KEY_H), +- KEY(5, 4, KEY_M), +- KEY(5, 5, TOSA_KEY_MENU), +- KEY(5, 7, KEY_UP), +- KEY(5, 11, TOSA_KEY_FN), +- KEY(6, 1, KEY_X), +- KEY(6, 2, KEY_F), +- KEY(6, 3, KEY_SPACE), +- KEY(6, 4, KEY_APOSTROPHE), +- KEY(6, 5, TOSA_KEY_MAIL), +- KEY(6, 6, KEY_LEFT), +- KEY(6, 7, KEY_DOWN), +- KEY(6, 8, KEY_RIGHT), ++ KEY(0, 1, KEY_W), ++ KEY(0, 5, KEY_K), ++ KEY(0, 6, KEY_BACKSPACE), ++ KEY(0, 7, KEY_P), ++ KEY(1, 0, KEY_Q), ++ KEY(1, 1, KEY_E), ++ KEY(1, 2, KEY_T), ++ KEY(1, 3, KEY_Y), ++ KEY(1, 5, KEY_O), ++ KEY(1, 6, KEY_I), ++ KEY(1, 7, KEY_COMMA), ++ KEY(2, 0, KEY_A), ++ KEY(2, 1, KEY_D), ++ KEY(2, 2, KEY_G), ++ KEY(2, 3, KEY_U), ++ KEY(2, 5, KEY_L), ++ KEY(2, 6, KEY_ENTER), ++ KEY(2, 7, KEY_DOT), ++ KEY(3, 0, KEY_Z), ++ KEY(3, 1, KEY_C), ++ KEY(3, 2, KEY_V), ++ KEY(3, 3, KEY_J), ++ KEY(3, 4, TOSA_KEY_ADDRESSBOOK), ++ KEY(3, 5, TOSA_KEY_CANCEL), ++ KEY(3, 6, TOSA_KEY_CENTER), ++ KEY(3, 7, TOSA_KEY_OK), ++ KEY(3, 8, KEY_LEFTSHIFT), ++ KEY(4, 0, KEY_S), ++ KEY(4, 1, KEY_R), ++ KEY(4, 2, KEY_B), ++ KEY(4, 3, KEY_N), ++ KEY(4, 4, TOSA_KEY_CALENDAR), ++ KEY(4, 5, TOSA_KEY_HOMEPAGE), ++ KEY(4, 6, KEY_LEFTCTRL), ++ KEY(4, 7, TOSA_KEY_LIGHT), ++ KEY(4, 9, KEY_RIGHTSHIFT), ++ KEY(5, 0, KEY_TAB), ++ KEY(5, 1, KEY_SLASH), ++ KEY(5, 2, KEY_H), ++ KEY(5, 3, KEY_M), ++ KEY(5, 4, TOSA_KEY_MENU), ++ KEY(5, 6, KEY_UP), ++ KEY(5, 10, TOSA_KEY_FN), ++ KEY(6, 0, KEY_X), ++ KEY(6, 1, KEY_F), ++ KEY(6, 2, KEY_SPACE), ++ KEY(6, 3, KEY_APOSTROPHE), ++ KEY(6, 4, TOSA_KEY_MAIL), ++ KEY(6, 5, KEY_LEFT), ++ KEY(6, 6, KEY_DOWN), ++ KEY(6, 7, KEY_RIGHT), + }; + + static struct matrix_keymap_data tosakbd_keymap_data = { +diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c +index 3fab2046c8a4..0eea2d2e8563 100644 +--- a/arch/mips/mm/dma-default.c ++++ b/arch/mips/mm/dma-default.c +@@ -30,16 +30,20 @@ static inline struct page *dma_addr_to_page(struct device *dev, + } + + /* ++ * The affected CPUs below in 'cpu_needs_post_dma_flush()' can ++ * speculatively fill random cachelines with stale data at any time, ++ * requiring an extra flush post-DMA. ++ * + * Warning on the terminology - Linux calls an uncached area coherent; + * MIPS terminology calls memory areas with hardware maintained coherency + * coherent. + */ +- +-static inline int cpu_is_noncoherent_r10000(struct device *dev) ++static inline int cpu_needs_post_dma_flush(struct device *dev) + { + return !plat_device_is_coherent(dev) && + (current_cpu_type() == CPU_R10000 || +- current_cpu_type() == CPU_R12000); ++ current_cpu_type() == CPU_R12000 || ++ current_cpu_type() == CPU_BMIPS5000); + } + + static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp) +@@ -209,7 +213,7 @@ static inline void __dma_sync(struct page *page, + static void mips_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, + size_t size, enum dma_data_direction direction, struct dma_attrs *attrs) + { +- if (cpu_is_noncoherent_r10000(dev)) ++ if (cpu_needs_post_dma_flush(dev)) + __dma_sync(dma_addr_to_page(dev, dma_addr), + dma_addr & ~PAGE_MASK, size, direction); + +@@ -260,7 +264,7 @@ static void mips_dma_unmap_sg(struct device *dev, struct scatterlist *sg, + static void mips_dma_sync_single_for_cpu(struct device *dev, + dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) + { +- if (cpu_is_noncoherent_r10000(dev)) ++ if (cpu_needs_post_dma_flush(dev)) + __dma_sync(dma_addr_to_page(dev, dma_handle), + dma_handle & ~PAGE_MASK, size, direction); + } +@@ -281,7 +285,7 @@ static void mips_dma_sync_sg_for_cpu(struct device *dev, + + /* Make sure that gcc doesn't leave the empty loop body. */ + for (i = 0; i < nelems; i++, sg++) { +- if (cpu_is_noncoherent_r10000(dev)) ++ if (cpu_needs_post_dma_flush(dev)) + __dma_sync(sg_page(sg), sg->offset, sg->length, + direction); + } +diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c +index 454548c309f1..8a67b7c019b8 100644 +--- a/arch/x86/platform/efi/efi.c ++++ b/arch/x86/platform/efi/efi.c +@@ -744,13 +744,6 @@ void __init efi_init(void) + + set_bit(EFI_MEMMAP, &x86_efi_facility); + +-#ifdef CONFIG_X86_32 +- if (efi_is_native()) { +- x86_platform.get_wallclock = efi_get_time; +- x86_platform.set_wallclock = efi_set_rtc_mmss; +- } +-#endif +- + #if EFI_DEBUG + print_efi_memmap(); + #endif +diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c +index 585c3b279feb..850246206b12 100644 +--- a/crypto/algif_hash.c ++++ b/crypto/algif_hash.c +@@ -117,9 +117,6 @@ static ssize_t hash_sendpage(struct socket *sock, struct page *page, + if (flags & MSG_SENDPAGE_NOTLAST) + flags |= MSG_MORE; + +- if (flags & MSG_SENDPAGE_NOTLAST) +- flags |= MSG_MORE; +- + lock_sock(sk); + sg_init_table(ctx->sgl.sg, 1); + sg_set_page(ctx->sgl.sg, page, size, offset); +diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c +index 918a3b4148b8..a19c027b29bd 100644 +--- a/crypto/algif_skcipher.c ++++ b/crypto/algif_skcipher.c +@@ -381,9 +381,6 @@ static ssize_t skcipher_sendpage(struct socket *sock, struct page *page, + if (flags & MSG_SENDPAGE_NOTLAST) + flags |= MSG_MORE; + +- if (flags & MSG_SENDPAGE_NOTLAST) +- flags |= MSG_MORE; +- + lock_sock(sk); + if (!ctx->more && ctx->used) + goto unlock; +diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c +index bd1f18c341d5..c22b5e7849f8 100644 +--- a/drivers/gpu/drm/radeon/si.c ++++ b/drivers/gpu/drm/radeon/si.c +@@ -2479,8 +2479,15 @@ static int si_mc_init(struct radeon_device *rdev) + rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); + rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); + /* size in MB on si */ +- rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; +- rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; ++ tmp = RREG32(CONFIG_MEMSIZE); ++ /* some boards may have garbage in the upper 16 bits */ ++ if (tmp & 0xffff0000) { ++ DRM_INFO("Probable bad vram size: 0x%08x\n", tmp); ++ if (tmp & 0xffff) ++ tmp &= 0xffff; ++ } ++ rdev->mc.mc_vram_size = tmp * 1024ULL * 1024ULL; ++ rdev->mc.real_vram_size = rdev->mc.mc_vram_size; + rdev->mc.visible_vram_size = rdev->mc.aper_size; + si_vram_gtt_location(rdev, &rdev->mc); + radeon_update_bandwidth_info(rdev); +diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c +index 5850b7706088..a97a62063356 100644 +--- a/drivers/hwmon/w83l786ng.c ++++ b/drivers/hwmon/w83l786ng.c +@@ -510,7 +510,7 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr, + mutex_lock(&data->update_lock); + reg = w83l786ng_read_value(client, W83L786NG_REG_FAN_CFG); + data->pwm_enable[nr] = val; +- reg &= ~(0x02 << W83L786NG_PWM_ENABLE_SHIFT[nr]); ++ reg &= ~(0x03 << W83L786NG_PWM_ENABLE_SHIFT[nr]); + reg |= (val - 1) << W83L786NG_PWM_ENABLE_SHIFT[nr]; + w83l786ng_write_value(client, W83L786NG_REG_FAN_CFG, reg); + mutex_unlock(&data->update_lock); +@@ -781,7 +781,7 @@ static struct w83l786ng_data *w83l786ng_update_device(struct device *dev) + ((pwmcfg >> W83L786NG_PWM_MODE_SHIFT[i]) & 1) + ? 0 : 1; + data->pwm_enable[i] = +- ((pwmcfg >> W83L786NG_PWM_ENABLE_SHIFT[i]) & 2) + 1; ++ ((pwmcfg >> W83L786NG_PWM_ENABLE_SHIFT[i]) & 3) + 1; + data->pwm[i] = w83l786ng_read_value(client, + W83L786NG_REG_PWM[i]); + } +diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c +index 22cd96f58c99..ce384a449a65 100644 +--- a/drivers/input/touchscreen/usbtouchscreen.c ++++ b/drivers/input/touchscreen/usbtouchscreen.c +@@ -106,6 +106,7 @@ struct usbtouch_device_info { + struct usbtouch_usb { + unsigned char *data; + dma_addr_t data_dma; ++ int data_size; + unsigned char *buffer; + int buf_len; + struct urb *irq; +@@ -1474,7 +1475,7 @@ static int usbtouch_reset_resume(struct usb_interface *intf) + static void usbtouch_free_buffers(struct usb_device *udev, + struct usbtouch_usb *usbtouch) + { +- usb_free_coherent(udev, usbtouch->type->rept_size, ++ usb_free_coherent(udev, usbtouch->data_size, + usbtouch->data, usbtouch->data_dma); + kfree(usbtouch->buffer); + } +@@ -1519,7 +1520,20 @@ static int usbtouch_probe(struct usb_interface *intf, + if (!type->process_pkt) + type->process_pkt = usbtouch_process_pkt; + +- usbtouch->data = usb_alloc_coherent(udev, type->rept_size, ++ usbtouch->data_size = type->rept_size; ++ if (type->get_pkt_len) { ++ /* ++ * When dealing with variable-length packets we should ++ * not request more than wMaxPacketSize bytes at once ++ * as we do not know if there is more data coming or ++ * we filled exactly wMaxPacketSize bytes and there is ++ * nothing else. ++ */ ++ usbtouch->data_size = min(usbtouch->data_size, ++ usb_endpoint_maxp(endpoint)); ++ } ++ ++ usbtouch->data = usb_alloc_coherent(udev, usbtouch->data_size, + GFP_KERNEL, &usbtouch->data_dma); + if (!usbtouch->data) + goto out_free; +@@ -1578,12 +1592,12 @@ static int usbtouch_probe(struct usb_interface *intf, + if (usb_endpoint_type(endpoint) == USB_ENDPOINT_XFER_INT) + usb_fill_int_urb(usbtouch->irq, udev, + usb_rcvintpipe(udev, endpoint->bEndpointAddress), +- usbtouch->data, type->rept_size, ++ usbtouch->data, usbtouch->data_size, + usbtouch_irq, usbtouch, endpoint->bInterval); + else + usb_fill_bulk_urb(usbtouch->irq, udev, + usb_rcvbulkpipe(udev, endpoint->bEndpointAddress), +- usbtouch->data, type->rept_size, ++ usbtouch->data, usbtouch->data_size, + usbtouch_irq, usbtouch); + + usbtouch->irq->dev = udev; +diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c +index cc06a1e52423..4c260dc7910e 100644 +--- a/drivers/md/dm-bufio.c ++++ b/drivers/md/dm-bufio.c +@@ -1642,6 +1642,11 @@ static int __init dm_bufio_init(void) + { + __u64 mem; + ++ dm_bufio_allocated_kmem_cache = 0; ++ dm_bufio_allocated_get_free_pages = 0; ++ dm_bufio_allocated_vmalloc = 0; ++ dm_bufio_current_allocated = 0; ++ + memset(&dm_bufio_caches, 0, sizeof dm_bufio_caches); + memset(&dm_bufio_cache_names, 0, sizeof dm_bufio_cache_names); + +diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c +index ee99912596cb..fb4bf9bac1a7 100644 +--- a/drivers/md/dm-delay.c ++++ b/drivers/md/dm-delay.c +@@ -20,6 +20,7 @@ + struct delay_c { + struct timer_list delay_timer; + struct mutex timer_lock; ++ struct workqueue_struct *kdelayd_wq; + struct work_struct flush_expired_bios; + struct list_head delayed_bios; + atomic_t may_delay; +@@ -45,14 +46,13 @@ struct dm_delay_info { + + static DEFINE_MUTEX(delayed_bios_lock); + +-static struct workqueue_struct *kdelayd_wq; + static struct kmem_cache *delayed_cache; + + static void handle_delayed_timer(unsigned long data) + { + struct delay_c *dc = (struct delay_c *)data; + +- queue_work(kdelayd_wq, &dc->flush_expired_bios); ++ queue_work(dc->kdelayd_wq, &dc->flush_expired_bios); + } + + static void queue_timeout(struct delay_c *dc, unsigned long expires) +@@ -191,6 +191,12 @@ out: + goto bad_dev_write; + } + ++ dc->kdelayd_wq = alloc_workqueue("kdelayd", WQ_MEM_RECLAIM, 0); ++ if (!dc->kdelayd_wq) { ++ DMERR("Couldn't start kdelayd"); ++ goto bad_queue; ++ } ++ + setup_timer(&dc->delay_timer, handle_delayed_timer, (unsigned long)dc); + + INIT_WORK(&dc->flush_expired_bios, flush_expired_bios); +@@ -203,6 +209,8 @@ out: + ti->private = dc; + return 0; + ++bad_queue: ++ mempool_destroy(dc->delayed_pool); + bad_dev_write: + if (dc->dev_write) + dm_put_device(ti, dc->dev_write); +@@ -217,7 +225,7 @@ static void delay_dtr(struct dm_target *ti) + { + struct delay_c *dc = ti->private; + +- flush_workqueue(kdelayd_wq); ++ destroy_workqueue(dc->kdelayd_wq); + + dm_put_device(ti, dc->dev_read); + +@@ -351,12 +359,6 @@ static int __init dm_delay_init(void) + { + int r = -ENOMEM; + +- kdelayd_wq = alloc_workqueue("kdelayd", WQ_MEM_RECLAIM, 0); +- if (!kdelayd_wq) { +- DMERR("Couldn't start kdelayd"); +- goto bad_queue; +- } +- + delayed_cache = KMEM_CACHE(dm_delay_info, 0); + if (!delayed_cache) { + DMERR("Couldn't create delayed bio cache."); +@@ -374,8 +376,6 @@ static int __init dm_delay_init(void) + bad_register: + kmem_cache_destroy(delayed_cache); + bad_memcache: +- destroy_workqueue(kdelayd_wq); +-bad_queue: + return r; + } + +@@ -383,7 +383,6 @@ static void __exit dm_delay_exit(void) + { + dm_unregister_target(&delay_target); + kmem_cache_destroy(delayed_cache); +- destroy_workqueue(kdelayd_wq); + } + + /* Module hooks */ +diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c +index d509f236bd54..43e19b76af8c 100644 +--- a/drivers/md/dm-table.c ++++ b/drivers/md/dm-table.c +@@ -215,6 +215,11 @@ int dm_table_create(struct dm_table **result, fmode_t mode, + + num_targets = dm_round_up(num_targets, KEYS_PER_NODE); + ++ if (!num_targets) { ++ kfree(t); ++ return -ENOMEM; ++ } ++ + if (alloc_targets(t, num_targets)) { + kfree(t); + t = NULL; +diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c +index dc474bc6522d..7029c8016dd5 100644 +--- a/drivers/rtc/rtc-at91rm9200.c ++++ b/drivers/rtc/rtc-at91rm9200.c +@@ -162,6 +162,8 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) + + at91_alarm_year = tm.tm_year; + ++ tm.tm_mon = alrm->time.tm_mon; ++ tm.tm_mday = alrm->time.tm_mday; + tm.tm_hour = alrm->time.tm_hour; + tm.tm_min = alrm->time.tm_min; + tm.tm_sec = alrm->time.tm_sec; +diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c +index 661ba2e03892..6e936c54f113 100644 +--- a/drivers/staging/comedi/drivers/pcmuio.c ++++ b/drivers/staging/comedi/drivers/pcmuio.c +@@ -464,13 +464,13 @@ static int pcmuio_detach(struct comedi_device *dev) + if (dev->iobase) + release_region(dev->iobase, ASIC_IOSIZE * thisboard->num_asics); + +- for (i = 0; i < MAX_ASICS; ++i) { +- if (devpriv->asics[i].irq) +- free_irq(devpriv->asics[i].irq, dev); +- } +- +- if (devpriv && devpriv->sprivs) ++ if (devpriv) { ++ for (i = 0; i < MAX_ASICS; ++i) { ++ if (devpriv->asics[i].irq) ++ free_irq(devpriv->asics[i].irq, dev); ++ } + kfree(devpriv->sprivs); ++ } + + return 0; + } +diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c +index 526de2efa125..0316780103b5 100644 +--- a/drivers/staging/comedi/drivers/ssv_dnp.c ++++ b/drivers/staging/comedi/drivers/ssv_dnp.c +@@ -251,11 +251,11 @@ static int dnp_dio_insn_bits(struct comedi_device *dev, + + /* on return, data[1] contains the value of the digital input lines. */ + outb(PADR, CSCIR); +- data[0] = inb(CSCDR); ++ data[1] = inb(CSCDR); + outb(PBDR, CSCIR); +- data[0] += inb(CSCDR) << 8; ++ data[1] += inb(CSCDR) << 8; + outb(PCDR, CSCIR); +- data[0] += ((inb(CSCDR) & 0xF0) << 12); ++ data[1] += ((inb(CSCDR) & 0xF0) << 12); + + return 2; + +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 82fce32ca229..14476faf9a00 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -3891,8 +3891,9 @@ static void hub_events(void) + hub->hdev->children[i - 1]; + + dev_dbg(hub_dev, "warm reset port %d\n", i); +- if (!udev || !(portstatus & +- USB_PORT_STAT_CONNECTION)) { ++ if (!udev || ++ !(portstatus & USB_PORT_STAT_CONNECTION) || ++ udev->state == USB_STATE_NOTATTACHED) { + status = hub_port_reset(hub, i, + NULL, HUB_BH_RESET_TIME, + true); +diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c +index e4d87d700554..5bf2bc00821b 100644 +--- a/drivers/usb/dwc3/ep0.c ++++ b/drivers/usb/dwc3/ep0.c +@@ -380,6 +380,8 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc, + dep = dwc3_wIndex_to_dep(dwc, wIndex); + if (!dep) + return -EINVAL; ++ if (set == 0 && (dep->flags & DWC3_EP_WEDGE)) ++ break; + ret = __dwc3_gadget_ep_set_halt(dep, set); + if (ret) + return -EINVAL; +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index 6d6fb88913c8..80e3094c8e19 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -1101,9 +1101,6 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value) + else + dep->flags |= DWC3_EP_STALL; + } else { +- if (dep->flags & DWC3_EP_WEDGE) +- return 0; +- + ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, + DWC3_DEPCMD_CLEARSTALL, ¶ms); + if (ret) +@@ -1111,7 +1108,7 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value) + value ? "set" : "clear", + dep->name); + else +- dep->flags &= ~DWC3_EP_STALL; ++ dep->flags &= ~(DWC3_EP_STALL | DWC3_EP_WEDGE); + } + + return ret; +diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c +index baaebf2830fc..f28b6de05f90 100644 +--- a/drivers/usb/gadget/composite.c ++++ b/drivers/usb/gadget/composite.c +@@ -584,6 +584,7 @@ static void reset_config(struct usb_composite_dev *cdev) + bitmap_zero(f->endpoints, 32); + } + cdev->config = NULL; ++ cdev->delayed_status = 0; + } + + static int set_config(struct usb_composite_dev *cdev, +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index a5477554ecb6..66f5e5472c17 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -85,6 +85,7 @@ static void option_instat_callback(struct urb *urb); + #define HUAWEI_PRODUCT_K4505 0x1464 + #define HUAWEI_PRODUCT_K3765 0x1465 + #define HUAWEI_PRODUCT_K4605 0x14C6 ++#define HUAWEI_PRODUCT_E173S6 0x1C07 + + #define QUANTA_VENDOR_ID 0x0408 + #define QUANTA_PRODUCT_Q101 0xEA02 +@@ -586,6 +587,8 @@ static const struct usb_device_id option_ids[] = { + { 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 }, ++ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173S6, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1750, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t) &net_intf2_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1441, USB_CLASS_COMM, 0x02, 0xff) }, +@@ -648,6 +651,10 @@ static const struct usb_device_id option_ids[] = { + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6D) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6E) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x72) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x73) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x74) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x75) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x78) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x79) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7A) }, +@@ -702,6 +709,10 @@ static const struct usb_device_id option_ids[] = { + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6D) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6E) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x72) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x73) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x74) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x75) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x78) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x79) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7A) }, +@@ -756,6 +767,10 @@ static const struct usb_device_id option_ids[] = { + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x6D) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x6E) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x6F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x72) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x73) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x74) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x75) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x78) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x79) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x7A) }, +@@ -810,6 +825,10 @@ static const struct usb_device_id option_ids[] = { + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x6D) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x6E) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x6F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x72) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x73) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x74) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x75) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x78) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x79) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x7A) }, +@@ -864,6 +883,10 @@ static const struct usb_device_id option_ids[] = { + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x6D) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x6E) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x6F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x72) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x73) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x74) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x75) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x78) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x79) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x7A) }, +@@ -918,6 +941,10 @@ static const struct usb_device_id option_ids[] = { + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x6D) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x6E) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x6F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x72) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x73) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x74) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x75) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x78) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x79) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x7A) }, +diff --git a/drivers/watchdog/sc1200wdt.c b/drivers/watchdog/sc1200wdt.c +index 3fb83b0c28c2..ab6d3f56cbca 100644 +--- a/drivers/watchdog/sc1200wdt.c ++++ b/drivers/watchdog/sc1200wdt.c +@@ -409,8 +409,9 @@ static int __init sc1200wdt_init(void) + #if defined CONFIG_PNP + /* now that the user has specified an IO port and we haven't detected + * any devices, disable pnp support */ ++ if (isapnp) ++ pnp_unregister_driver(&scl200wdt_pnp_driver); + isapnp = 0; +- pnp_unregister_driver(&scl200wdt_pnp_driver); + #endif + + if (!request_region(io, io_len, SC1200_MODULE_NAME)) { +diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c +index 89d2a5803ae3..5ecfffe25334 100644 +--- a/fs/hpfs/file.c ++++ b/fs/hpfs/file.c +@@ -116,9 +116,12 @@ static int hpfs_write_begin(struct file *file, struct address_space *mapping, + hpfs_get_block, + &hpfs_i(mapping->host)->mmu_private); + if (unlikely(ret)) { +- loff_t isize = mapping->host->i_size; ++ loff_t isize; ++ hpfs_lock(mapping->host->i_sb); ++ isize = mapping->host->i_size; + if (pos + len > isize) + vmtruncate(mapping->host, isize); ++ hpfs_unlock(mapping->host->i_sb); + } + + return ret; +diff --git a/fs/nfs/blocklayout/extents.c b/fs/nfs/blocklayout/extents.c +index 1f9a6032796b..51f9ff25d475 100644 +--- a/fs/nfs/blocklayout/extents.c ++++ b/fs/nfs/blocklayout/extents.c +@@ -44,7 +44,7 @@ + static inline sector_t normalize(sector_t s, int base) + { + sector_t tmp = s; /* Since do_div modifies its argument */ +- return s - do_div(tmp, base); ++ return s - sector_div(tmp, base); + } + + static inline sector_t normalize_up(sector_t s, int base) +diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c +index 91f8ff547ab3..6a6c1fdb7892 100644 +--- a/fs/xfs/xfs_ioctl.c ++++ b/fs/xfs/xfs_ioctl.c +@@ -400,7 +400,8 @@ xfs_attrlist_by_handle( + return -XFS_ERROR(EPERM); + if (copy_from_user(&al_hreq, arg, sizeof(xfs_fsop_attrlist_handlereq_t))) + return -XFS_ERROR(EFAULT); +- if (al_hreq.buflen > XATTR_LIST_MAX) ++ if (al_hreq.buflen < sizeof(struct attrlist) || ++ al_hreq.buflen > XATTR_LIST_MAX) + return -XFS_ERROR(EINVAL); + + /* +diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c +index a849a5473aff..745ea4ea98ab 100644 +--- a/fs/xfs/xfs_ioctl32.c ++++ b/fs/xfs/xfs_ioctl32.c +@@ -361,7 +361,8 @@ xfs_compat_attrlist_by_handle( + if (copy_from_user(&al_hreq, arg, + sizeof(compat_xfs_fsop_attrlist_handlereq_t))) + return -XFS_ERROR(EFAULT); +- if (al_hreq.buflen > XATTR_LIST_MAX) ++ if (al_hreq.buflen < sizeof(struct attrlist) || ++ al_hreq.buflen > XATTR_LIST_MAX) + return -XFS_ERROR(EINVAL); + + /* +diff --git a/include/sound/memalloc.h b/include/sound/memalloc.h +index c42506212649..ab240bb608a8 100644 +--- a/include/sound/memalloc.h ++++ b/include/sound/memalloc.h +@@ -101,7 +101,7 @@ static inline unsigned int snd_sgbuf_aligned_pages(size_t size) + static inline dma_addr_t snd_sgbuf_get_addr(struct snd_sg_buf *sgbuf, size_t offset) + { + dma_addr_t addr = sgbuf->table[offset >> PAGE_SHIFT].addr; +- addr &= PAGE_MASK; ++ addr &= ~((dma_addr_t)PAGE_SIZE - 1); + return addr + offset % PAGE_SIZE; + } + +diff --git a/kernel/futex.c b/kernel/futex.c +index f0ee318df9c0..e564a9a3ea2a 100644 +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -285,7 +285,7 @@ again: + put_page(page); + /* serialize against __split_huge_page_splitting() */ + local_irq_disable(); +- if (likely(__get_user_pages_fast(address, 1, 1, &page) == 1)) { ++ if (likely(__get_user_pages_fast(address, 1, !ro, &page) == 1)) { + page_head = compound_head(page); + /* + * page_head is valid pointer but we must pin +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index 19e784237f7a..7949b5d1663f 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -1042,9 +1042,6 @@ int udp_sendpage(struct sock *sk, struct page *page, int offset, + if (flags & MSG_SENDPAGE_NOTLAST) + flags |= MSG_MORE; + +- if (flags & MSG_SENDPAGE_NOTLAST) +- flags |= MSG_MORE; +- + if (!up->pending) { + struct msghdr msg = { .msg_flags = flags|MSG_MORE }; + +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index 067aa2a23055..6937a84bef3a 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -763,7 +763,8 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx) + u16 sc; + u8 tid, ack_policy; + +- if (!ieee80211_is_data_qos(hdr->frame_control)) ++ if (!ieee80211_is_data_qos(hdr->frame_control) || ++ is_multicast_ether_addr(hdr->addr1)) + goto dont_reorder; + + /* +diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c +index 56262223190d..d32db4140aa0 100644 +--- a/security/selinux/hooks.c ++++ b/security/selinux/hooks.c +@@ -52,6 +52,7 @@ + #include + #include /* for local_port_range[] */ + #include /* struct or_callable used in sock_rcv_skb */ ++#include + #include + #include + #include +@@ -3733,6 +3734,30 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid) + return 0; + } + ++/** ++ * selinux_conn_sid - Determine the child socket label for a connection ++ * @sk_sid: the parent socket's SID ++ * @skb_sid: the packet's SID ++ * @conn_sid: the resulting connection SID ++ * ++ * If @skb_sid is valid then the user:role:type information from @sk_sid is ++ * combined with the MLS information from @skb_sid in order to create ++ * @conn_sid. If @skb_sid is not valid then then @conn_sid is simply a copy ++ * of @sk_sid. Returns zero on success, negative values on failure. ++ * ++ */ ++static int selinux_conn_sid(u32 sk_sid, u32 skb_sid, u32 *conn_sid) ++{ ++ int err = 0; ++ ++ if (skb_sid != SECSID_NULL) ++ err = security_sid_mls_copy(sk_sid, skb_sid, conn_sid); ++ else ++ *conn_sid = sk_sid; ++ ++ return err; ++} ++ + /* socket security operations */ + + static int socket_sockcreate_sid(const struct task_security_struct *tsec, +@@ -4354,7 +4379,7 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, + struct sk_security_struct *sksec = sk->sk_security; + int err; + u16 family = sk->sk_family; +- u32 newsid; ++ u32 connsid; + u32 peersid; + + /* handle mapped IPv4 packets arriving via IPv6 sockets */ +@@ -4364,16 +4389,11 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, + err = selinux_skb_peerlbl_sid(skb, family, &peersid); + if (err) + return err; +- if (peersid == SECSID_NULL) { +- req->secid = sksec->sid; +- req->peer_secid = SECSID_NULL; +- } else { +- err = security_sid_mls_copy(sksec->sid, peersid, &newsid); +- if (err) +- return err; +- req->secid = newsid; +- req->peer_secid = peersid; +- } ++ err = selinux_conn_sid(sksec->sid, peersid, &connsid); ++ if (err) ++ return err; ++ req->secid = connsid; ++ req->peer_secid = peersid; + + return selinux_netlbl_inet_conn_request(req, family); + } +@@ -4605,6 +4625,7 @@ static unsigned int selinux_ipv6_forward(unsigned int hooknum, + static unsigned int selinux_ip_output(struct sk_buff *skb, + u16 family) + { ++ struct sock *sk; + u32 sid; + + if (!netlbl_enabled()) +@@ -4613,8 +4634,27 @@ static unsigned int selinux_ip_output(struct sk_buff *skb, + /* we do this in the LOCAL_OUT path and not the POST_ROUTING path + * because we want to make sure we apply the necessary labeling + * before IPsec is applied so we can leverage AH protection */ +- if (skb->sk) { +- struct sk_security_struct *sksec = skb->sk->sk_security; ++ sk = skb->sk; ++ if (sk) { ++ struct sk_security_struct *sksec; ++ ++ if (sk->sk_state == TCP_LISTEN) ++ /* if the socket is the listening state then this ++ * packet is a SYN-ACK packet which means it needs to ++ * be labeled based on the connection/request_sock and ++ * not the parent socket. unfortunately, we can't ++ * lookup the request_sock yet as it isn't queued on ++ * the parent socket until after the SYN-ACK is sent. ++ * the "solution" is to simply pass the packet as-is ++ * as any IP option based labeling should be copied ++ * from the initial connection request (in the IP ++ * layer). it is far from ideal, but until we get a ++ * security label in the packet itself this is the ++ * best we can do. */ ++ return NF_ACCEPT; ++ ++ /* standard practice, label using the parent socket */ ++ sksec = sk->sk_security; + sid = sksec->sid; + } else + sid = SECINITSID_KERNEL; +@@ -4702,12 +4742,12 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, + if (!secmark_active && !peerlbl_active) + return NF_ACCEPT; + +- /* if the packet is being forwarded then get the peer label from the +- * packet itself; otherwise check to see if it is from a local +- * application or the kernel, if from an application get the peer label +- * from the sending socket, otherwise use the kernel's sid */ + sk = skb->sk; + if (sk == NULL) { ++ /* Without an associated socket the packet is either coming ++ * from the kernel or it is being forwarded; check the packet ++ * to determine which and if the packet is being forwarded ++ * query the packet directly to determine the security label. */ + if (skb->skb_iif) { + secmark_perm = PACKET__FORWARD_OUT; + if (selinux_skb_peerlbl_sid(skb, family, &peer_sid)) +@@ -4716,7 +4756,26 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, + secmark_perm = PACKET__SEND; + peer_sid = SECINITSID_KERNEL; + } ++ } else if (sk->sk_state == TCP_LISTEN) { ++ /* Locally generated packet but the associated socket is in the ++ * listening state which means this is a SYN-ACK packet. In ++ * this particular case the correct security label is assigned ++ * to the connection/request_sock but unfortunately we can't ++ * query the request_sock as it isn't queued on the parent ++ * socket until after the SYN-ACK packet is sent; the only ++ * viable choice is to regenerate the label like we do in ++ * selinux_inet_conn_request(). See also selinux_ip_output() ++ * for similar problems. */ ++ u32 skb_sid; ++ struct sk_security_struct *sksec = sk->sk_security; ++ if (selinux_skb_peerlbl_sid(skb, family, &skb_sid)) ++ return NF_DROP; ++ if (selinux_conn_sid(sksec->sid, skb_sid, &peer_sid)) ++ return NF_DROP; ++ secmark_perm = PACKET__SEND; + } else { ++ /* Locally generated packet, fetch the security label from the ++ * associated socket. */ + struct sk_security_struct *sksec = sk->sk_security; + peer_sid = sksec->sid; + secmark_perm = PACKET__SEND; +diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c +index 91a0a2f8cbc7..bc5ed1412382 100644 +--- a/virt/kvm/kvm_main.c ++++ b/virt/kvm/kvm_main.c +@@ -1668,6 +1668,9 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id) + int r; + struct kvm_vcpu *vcpu, *v; + ++ if (id >= KVM_MAX_VCPUS) ++ return -EINVAL; ++ + vcpu = kvm_arch_vcpu_create(kvm, id); + if (IS_ERR(vcpu)) + return PTR_ERR(vcpu); diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.75-76.patch b/patch/kernel/sun8i-default/0001-patch-3.4.75-76.patch new file mode 100644 index 000000000..57e6bf91f --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.75-76.patch @@ -0,0 +1,1260 @@ +diff --git a/Makefile b/Makefile +index 2d084a418789..8045c75414ae 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 75 ++SUBLEVEL = 76 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h +index 6afb13ad1611..241d2f305307 100644 +--- a/arch/powerpc/include/asm/exception-64s.h ++++ b/arch/powerpc/include/asm/exception-64s.h +@@ -163,7 +163,7 @@ do_kvm_##n: \ + subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \ + beq- 1f; \ + ld r1,PACAKSAVE(r13); /* kernel stack to use */ \ +-1: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \ ++1: cmpdi cr1,r1,-INT_FRAME_SIZE; /* check if r1 is in userspace */ \ + blt+ cr1,3f; /* abort if it is */ \ + li r1,(n); /* will be reloaded later */ \ + sth r1,PACA_TRAP_SAVE(r13); \ +diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S +index 1a3607b96635..1a5b6878ac61 100644 +--- a/arch/powerpc/kernel/head_64.S ++++ b/arch/powerpc/kernel/head_64.S +@@ -447,6 +447,7 @@ _STATIC(__after_prom_start) + mtctr r8 + bctr + ++.balign 8 + p_end: .llong _end - _stext + + 4: /* Now copy the rest of the kernel up to _end */ +diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c +index c3beaeef3f60..87135be08687 100644 +--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c ++++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c +@@ -393,11 +393,14 @@ static int kvmppc_mmu_book3s_64_hv_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, + slb_v = vcpu->kvm->arch.vrma_slb_v; + } + ++ preempt_disable(); + /* Find the HPTE in the hash table */ + index = kvmppc_hv_find_lock_hpte(kvm, eaddr, slb_v, + HPTE_V_VALID | HPTE_V_ABSENT); +- if (index < 0) ++ if (index < 0) { ++ preempt_enable(); + return -ENOENT; ++ } + hptep = (unsigned long *)(kvm->arch.hpt_virt + (index << 4)); + v = hptep[0] & ~HPTE_V_HVLOCK; + gr = kvm->arch.revmap[index].guest_rpte; +@@ -405,6 +408,7 @@ static int kvmppc_mmu_book3s_64_hv_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, + /* Unlock the HPTE */ + asm volatile("lwsync" : : : "memory"); + hptep[0] = v; ++ preempt_enable(); + + gpte->eaddr = eaddr; + gpte->vpage = ((v & HPTE_V_AVPN) << 4) | ((eaddr >> 12) & 0xfff); +diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c +index cec4daddbf31..eacf164eabb2 100644 +--- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c ++++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c +@@ -649,6 +649,10 @@ static int slb_base_page_shift[4] = { + 20, /* 1M, unsupported */ + }; + ++/* When called from virtmode, this func should be protected by ++ * preempt_disable(), otherwise, the holding of HPTE_V_HVLOCK ++ * can trigger deadlock issue. ++ */ + long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v, + unsigned long valid) + { +diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile +index 7b95f29e3174..3baff31e58cf 100644 +--- a/arch/sh/lib/Makefile ++++ b/arch/sh/lib/Makefile +@@ -6,7 +6,7 @@ lib-y = delay.o memmove.o memchr.o \ + checksum.o strlen.o div64.o div64-generic.o + + # Extracted from libgcc +-lib-y += movmem.o ashldi3.o ashrdi3.o lshrdi3.o \ ++obj-y += movmem.o ashldi3.o ashrdi3.o lshrdi3.o \ + ashlsi3.o ashrsi3.o ashiftrt.o lshrsi3.o \ + udiv_qrnnd.o + +diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c +index cd20cf1ef3ed..400b8c6eb8eb 100644 +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -4104,6 +4104,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { + { "ST3320[68]13AS", "SD1[5-9]", ATA_HORKAGE_NONCQ | + ATA_HORKAGE_FIRMWARE_WARN }, + ++ /* Seagate Momentus SpinPoint M8 seem to have FPMDA_AA issues */ ++ { "ST1000LM024 HN-M101MBB", "2AR10001", ATA_HORKAGE_BROKEN_FPDMA_AA }, ++ + /* Blacklist entries taken from Silicon Image 3124/3132 + Windows driver .inf file - also several Linux problem reports */ + { "HTS541060G9SA00", "MB3OC60D", ATA_HORKAGE_NONCQ, }, +diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig +index ef378b5b17e4..7de7a656c50b 100644 +--- a/drivers/dma/Kconfig ++++ b/drivers/dma/Kconfig +@@ -269,6 +269,7 @@ config NET_DMA + bool "Network: TCP receive copy offload" + depends on DMA_ENGINE && NET + default (INTEL_IOATDMA || FSL_DMA) ++ depends on BROKEN + help + This enables the use of DMA engines in the network stack to + offload receive copy-to-user operations, freeing CPU cycles. +diff --git a/drivers/gpio/gpio-msm-v2.c b/drivers/gpio/gpio-msm-v2.c +index 5cb1227d69cf..3104502611f1 100644 +--- a/drivers/gpio/gpio-msm-v2.c ++++ b/drivers/gpio/gpio-msm-v2.c +@@ -249,7 +249,7 @@ static void msm_gpio_irq_mask(struct irq_data *d) + + spin_lock_irqsave(&tlmm_lock, irq_flags); + writel(TARGET_PROC_NONE, GPIO_INTR_CFG_SU(gpio)); +- clear_gpio_bits(INTR_RAW_STATUS_EN | INTR_ENABLE, GPIO_INTR_CFG(gpio)); ++ clear_gpio_bits(BIT(INTR_RAW_STATUS_EN) | BIT(INTR_ENABLE), GPIO_INTR_CFG(gpio)); + __clear_bit(gpio, msm_gpio.enabled_irqs); + spin_unlock_irqrestore(&tlmm_lock, irq_flags); + } +@@ -261,7 +261,7 @@ static void msm_gpio_irq_unmask(struct irq_data *d) + + spin_lock_irqsave(&tlmm_lock, irq_flags); + __set_bit(gpio, msm_gpio.enabled_irqs); +- set_gpio_bits(INTR_RAW_STATUS_EN | INTR_ENABLE, GPIO_INTR_CFG(gpio)); ++ set_gpio_bits(BIT(INTR_RAW_STATUS_EN) | BIT(INTR_ENABLE), GPIO_INTR_CFG(gpio)); + writel(TARGET_PROC_SCORPION, GPIO_INTR_CFG_SU(gpio)); + spin_unlock_irqrestore(&tlmm_lock, irq_flags); + } +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index efe172f33602..d75dccb562f3 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -68,6 +68,8 @@ + #define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6) + /* Force reduced-blanking timings for detailed modes */ + #define EDID_QUIRK_FORCE_REDUCED_BLANKING (1 << 7) ++/* Force 8bpc */ ++#define EDID_QUIRK_FORCE_8BPC (1 << 8) + + struct detailed_mode_closure { + struct drm_connector *connector; +@@ -128,6 +130,9 @@ static struct edid_quirk { + + /* Medion MD 30217 PG */ + { "MED", 0x7b8, EDID_QUIRK_PREFER_LARGE_75 }, ++ ++ /* Panel in Samsung NP700G7A-S01PL notebook reports 6bpc */ ++ { "SEC", 0xd033, EDID_QUIRK_FORCE_8BPC }, + }; + + /*** DDC fetch and block validation ***/ +@@ -1782,6 +1787,9 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) + + drm_add_display_info(edid, &connector->display_info); + ++ if (quirks & EDID_QUIRK_FORCE_8BPC) ++ connector->display_info.bpc = 8; ++ + return num_modes; + } + EXPORT_SYMBOL(drm_add_edid_modes); +diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c +index f5387b3e699f..f481da3a4f29 100644 +--- a/drivers/gpu/drm/radeon/ni.c ++++ b/drivers/gpu/drm/radeon/ni.c +@@ -672,6 +672,10 @@ static void cayman_gpu_init(struct radeon_device *rdev) + (rdev->pdev->device == 0x999C)) { + rdev->config.cayman.max_simds_per_se = 6; + rdev->config.cayman.max_backends_per_se = 2; ++ rdev->config.cayman.max_hw_contexts = 8; ++ rdev->config.cayman.sx_max_export_size = 256; ++ rdev->config.cayman.sx_max_export_pos_size = 64; ++ rdev->config.cayman.sx_max_export_smx_size = 192; + } else if ((rdev->pdev->device == 0x9903) || + (rdev->pdev->device == 0x9904) || + (rdev->pdev->device == 0x990A) || +@@ -682,6 +686,10 @@ static void cayman_gpu_init(struct radeon_device *rdev) + (rdev->pdev->device == 0x999D)) { + rdev->config.cayman.max_simds_per_se = 4; + rdev->config.cayman.max_backends_per_se = 2; ++ rdev->config.cayman.max_hw_contexts = 8; ++ rdev->config.cayman.sx_max_export_size = 256; ++ rdev->config.cayman.sx_max_export_pos_size = 64; ++ rdev->config.cayman.sx_max_export_smx_size = 192; + } else if ((rdev->pdev->device == 0x9919) || + (rdev->pdev->device == 0x9990) || + (rdev->pdev->device == 0x9991) || +@@ -692,9 +700,17 @@ static void cayman_gpu_init(struct radeon_device *rdev) + (rdev->pdev->device == 0x99A0)) { + rdev->config.cayman.max_simds_per_se = 3; + rdev->config.cayman.max_backends_per_se = 1; ++ rdev->config.cayman.max_hw_contexts = 4; ++ rdev->config.cayman.sx_max_export_size = 128; ++ rdev->config.cayman.sx_max_export_pos_size = 32; ++ rdev->config.cayman.sx_max_export_smx_size = 96; + } else { + rdev->config.cayman.max_simds_per_se = 2; + rdev->config.cayman.max_backends_per_se = 1; ++ rdev->config.cayman.max_hw_contexts = 4; ++ rdev->config.cayman.sx_max_export_size = 128; ++ rdev->config.cayman.sx_max_export_pos_size = 32; ++ rdev->config.cayman.sx_max_export_smx_size = 96; + } + rdev->config.cayman.max_texture_channel_caches = 2; + rdev->config.cayman.max_gprs = 256; +@@ -702,10 +718,6 @@ static void cayman_gpu_init(struct radeon_device *rdev) + rdev->config.cayman.max_gs_threads = 32; + rdev->config.cayman.max_stack_entries = 512; + rdev->config.cayman.sx_num_of_sets = 8; +- rdev->config.cayman.sx_max_export_size = 256; +- rdev->config.cayman.sx_max_export_pos_size = 64; +- rdev->config.cayman.sx_max_export_smx_size = 192; +- rdev->config.cayman.max_hw_contexts = 8; + rdev->config.cayman.sq_num_cf_insts = 2; + + rdev->config.cayman.sc_prim_fifo_size = 0x40; +diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c +index a97a62063356..284d469af326 100644 +--- a/drivers/hwmon/w83l786ng.c ++++ b/drivers/hwmon/w83l786ng.c +@@ -481,9 +481,11 @@ store_pwm(struct device *dev, struct device_attribute *attr, + if (err) + return err; + val = SENSORS_LIMIT(val, 0, 255); ++ val = DIV_ROUND_CLOSEST(val, 0x11); + + mutex_lock(&data->update_lock); +- data->pwm[nr] = val; ++ data->pwm[nr] = val * 0x11; ++ val |= w83l786ng_read_value(client, W83L786NG_REG_PWM[nr]) & 0xf0; + w83l786ng_write_value(client, W83L786NG_REG_PWM[nr], val); + mutex_unlock(&data->update_lock); + return count; +@@ -782,8 +784,9 @@ static struct w83l786ng_data *w83l786ng_update_device(struct device *dev) + ? 0 : 1; + data->pwm_enable[i] = + ((pwmcfg >> W83L786NG_PWM_ENABLE_SHIFT[i]) & 3) + 1; +- data->pwm[i] = w83l786ng_read_value(client, +- W83L786NG_REG_PWM[i]); ++ data->pwm[i] = ++ (w83l786ng_read_value(client, W83L786NG_REG_PWM[i]) ++ & 0x0f) * 0x11; + } + + +diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c +index d0f59c3f87ef..8d1ebd332292 100644 +--- a/drivers/idle/intel_idle.c ++++ b/drivers/idle/intel_idle.c +@@ -169,6 +169,38 @@ static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = { + .enter = &intel_idle }, + }; + ++static struct cpuidle_state ivb_cstates[MWAIT_MAX_NUM_CSTATES] = { ++ { /* MWAIT C0 */ }, ++ { /* MWAIT C1 */ ++ .name = "C1-IVB", ++ .desc = "MWAIT 0x00", ++ .flags = CPUIDLE_FLAG_TIME_VALID, ++ .exit_latency = 1, ++ .target_residency = 1, ++ .enter = &intel_idle }, ++ { /* MWAIT C2 */ ++ .name = "C3-IVB", ++ .desc = "MWAIT 0x10", ++ .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, ++ .exit_latency = 59, ++ .target_residency = 156, ++ .enter = &intel_idle }, ++ { /* MWAIT C3 */ ++ .name = "C6-IVB", ++ .desc = "MWAIT 0x20", ++ .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, ++ .exit_latency = 80, ++ .target_residency = 300, ++ .enter = &intel_idle }, ++ { /* MWAIT C4 */ ++ .name = "C7-IVB", ++ .desc = "MWAIT 0x30", ++ .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, ++ .exit_latency = 87, ++ .target_residency = 300, ++ .enter = &intel_idle }, ++}; ++ + static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { + { /* MWAIT C0 */ }, + { /* MWAIT C1 */ +@@ -347,6 +379,10 @@ static const struct idle_cpu idle_cpu_snb = { + .state_table = snb_cstates, + }; + ++static const struct idle_cpu idle_cpu_ivb = { ++ .state_table = ivb_cstates, ++}; ++ + #define ICPU(model, cpu) \ + { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&cpu } + +@@ -362,6 +398,8 @@ static const struct x86_cpu_id intel_idle_ids[] = { + ICPU(0x2f, idle_cpu_nehalem), + ICPU(0x2a, idle_cpu_snb), + ICPU(0x2d, idle_cpu_snb), ++ ICPU(0x3a, idle_cpu_ivb), ++ ICPU(0x3e, idle_cpu_ivb), + {} + }; + MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids); +diff --git a/drivers/input/input.c b/drivers/input/input.c +index 8921c6180c51..d56c407aa096 100644 +--- a/drivers/input/input.c ++++ b/drivers/input/input.c +@@ -1707,6 +1707,10 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int + break; + + case EV_ABS: ++ input_alloc_absinfo(dev); ++ if (!dev->absinfo) ++ return; ++ + __set_bit(code, dev->absbit); + break; + +diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c +index 905b16faee41..17851833f839 100644 +--- a/drivers/net/usb/dm9601.c ++++ b/drivers/net/usb/dm9601.c +@@ -445,7 +445,12 @@ static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf) + dev->net->ethtool_ops = &dm9601_ethtool_ops; + dev->net->hard_header_len += DM_TX_OVERHEAD; + dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; +- dev->rx_urb_size = dev->net->mtu + ETH_HLEN + DM_RX_OVERHEAD; ++ ++ /* dm9620/21a require room for 4 byte padding, even in dm9601 ++ * mode, so we need +1 to be able to receive full size ++ * ethernet frames. ++ */ ++ dev->rx_urb_size = dev->net->mtu + ETH_HLEN + DM_RX_OVERHEAD + 1; + + dev->mii.dev = dev->net; + dev->mii.mdio_read = dm9601_mdio_read; +@@ -531,7 +536,7 @@ static int dm9601_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + static struct sk_buff *dm9601_tx_fixup(struct usbnet *dev, struct sk_buff *skb, + gfp_t flags) + { +- int len; ++ int len, pad; + + /* format: + b1: packet length low +@@ -539,12 +544,23 @@ static struct sk_buff *dm9601_tx_fixup(struct usbnet *dev, struct sk_buff *skb, + b3..n: packet data + */ + +- len = skb->len; ++ len = skb->len + DM_TX_OVERHEAD; + +- if (skb_headroom(skb) < DM_TX_OVERHEAD) { ++ /* workaround for dm962x errata with tx fifo getting out of ++ * sync if a USB bulk transfer retry happens right after a ++ * packet with odd / maxpacket length by adding up to 3 bytes ++ * padding. ++ */ ++ while ((len & 1) || !(len % dev->maxpacket)) ++ len++; ++ ++ len -= DM_TX_OVERHEAD; /* hw header doesn't count as part of length */ ++ pad = len - skb->len; ++ ++ if (skb_headroom(skb) < DM_TX_OVERHEAD || skb_tailroom(skb) < pad) { + struct sk_buff *skb2; + +- skb2 = skb_copy_expand(skb, DM_TX_OVERHEAD, 0, flags); ++ skb2 = skb_copy_expand(skb, DM_TX_OVERHEAD, pad, flags); + dev_kfree_skb_any(skb); + skb = skb2; + if (!skb) +@@ -553,10 +569,10 @@ static struct sk_buff *dm9601_tx_fixup(struct usbnet *dev, struct sk_buff *skb, + + __skb_push(skb, DM_TX_OVERHEAD); + +- /* usbnet adds padding if length is a multiple of packet size +- if so, adjust length value in header */ +- if ((skb->len % dev->maxpacket) == 0) +- len++; ++ if (pad) { ++ memset(skb->data + skb->len, 0, pad); ++ __skb_put(skb, pad); ++ } + + skb->data[0] = len; + skb->data[1] = len >> 8; +diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c +index aa2abaf31cba..fa7581a50495 100644 +--- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c ++++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c +@@ -76,9 +76,16 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) + mask2 |= ATH9K_INT_CST; + if (isr2 & AR_ISR_S2_TSFOOR) + mask2 |= ATH9K_INT_TSFOOR; ++ ++ if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) { ++ REG_WRITE(ah, AR_ISR_S2, isr2); ++ isr &= ~AR_ISR_BCNMISC; ++ } + } + +- isr = REG_READ(ah, AR_ISR_RAC); ++ if (pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED) ++ isr = REG_READ(ah, AR_ISR_RAC); ++ + if (isr == 0xffffffff) { + *masked = 0; + return false; +@@ -97,11 +104,23 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) + + *masked |= ATH9K_INT_TX; + +- s0_s = REG_READ(ah, AR_ISR_S0_S); ++ if (pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED) { ++ s0_s = REG_READ(ah, AR_ISR_S0_S); ++ s1_s = REG_READ(ah, AR_ISR_S1_S); ++ } else { ++ s0_s = REG_READ(ah, AR_ISR_S0); ++ REG_WRITE(ah, AR_ISR_S0, s0_s); ++ s1_s = REG_READ(ah, AR_ISR_S1); ++ REG_WRITE(ah, AR_ISR_S1, s1_s); ++ ++ isr &= ~(AR_ISR_TXOK | ++ AR_ISR_TXDESC | ++ AR_ISR_TXERR | ++ AR_ISR_TXEOL); ++ } ++ + ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK); + ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC); +- +- s1_s = REG_READ(ah, AR_ISR_S1_S); + ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR); + ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL); + } +@@ -114,13 +133,15 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) + *masked |= mask2; + } + +- if (AR_SREV_9100(ah)) +- return true; +- +- if (isr & AR_ISR_GENTMR) { ++ if (!AR_SREV_9100(ah) && (isr & AR_ISR_GENTMR)) { + u32 s5_s; + +- s5_s = REG_READ(ah, AR_ISR_S5_S); ++ if (pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED) { ++ s5_s = REG_READ(ah, AR_ISR_S5_S); ++ } else { ++ s5_s = REG_READ(ah, AR_ISR_S5); ++ } ++ + ah->intr_gen_timer_trigger = + MS(s5_s, AR_ISR_S5_GENTIMER_TRIG); + +@@ -133,8 +154,21 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) + if ((s5_s & AR_ISR_S5_TIM_TIMER) && + !(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) + *masked |= ATH9K_INT_TIM_TIMER; ++ ++ if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) { ++ REG_WRITE(ah, AR_ISR_S5, s5_s); ++ isr &= ~AR_ISR_GENTMR; ++ } + } + ++ if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) { ++ REG_WRITE(ah, AR_ISR, isr); ++ REG_READ(ah, AR_ISR); ++ } ++ ++ if (AR_SREV_9100(ah)) ++ return true; ++ + if (sync_cause) { + fatal_int = + (sync_cause & +diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c +index abbd6effd60d..204619e29a17 100644 +--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c ++++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c +@@ -139,21 +139,26 @@ static void ath9k_htc_bssid_iter(void *data, u8 *mac, struct ieee80211_vif *vif) + struct ath9k_vif_iter_data *iter_data = data; + int i; + +- for (i = 0; i < ETH_ALEN; i++) +- iter_data->mask[i] &= ~(iter_data->hw_macaddr[i] ^ mac[i]); ++ if (iter_data->hw_macaddr != NULL) { ++ for (i = 0; i < ETH_ALEN; i++) ++ iter_data->mask[i] &= ~(iter_data->hw_macaddr[i] ^ mac[i]); ++ } else { ++ iter_data->hw_macaddr = mac; ++ } + } + +-static void ath9k_htc_set_bssid_mask(struct ath9k_htc_priv *priv, ++static void ath9k_htc_set_mac_bssid_mask(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif) + { + struct ath_common *common = ath9k_hw_common(priv->ah); + struct ath9k_vif_iter_data iter_data; + + /* +- * Use the hardware MAC address as reference, the hardware uses it +- * together with the BSSID mask when matching addresses. ++ * Pick the MAC address of the first interface as the new hardware ++ * MAC address. The hardware will use it together with the BSSID mask ++ * when matching addresses. + */ +- iter_data.hw_macaddr = common->macaddr; ++ iter_data.hw_macaddr = NULL; + memset(&iter_data.mask, 0xff, ETH_ALEN); + + if (vif) +@@ -164,6 +169,10 @@ static void ath9k_htc_set_bssid_mask(struct ath9k_htc_priv *priv, + &iter_data); + + memcpy(common->bssidmask, iter_data.mask, ETH_ALEN); ++ ++ if (iter_data.hw_macaddr) ++ memcpy(common->macaddr, iter_data.hw_macaddr, ETH_ALEN); ++ + ath_hw_setbssidmask(common); + } + +@@ -1091,7 +1100,7 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, + goto out; + } + +- ath9k_htc_set_bssid_mask(priv, vif); ++ ath9k_htc_set_mac_bssid_mask(priv, vif); + + priv->vif_slot |= (1 << avp->index); + priv->nvifs++; +@@ -1154,7 +1163,7 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, + + ath9k_htc_set_opmode(priv); + +- ath9k_htc_set_bssid_mask(priv, vif); ++ ath9k_htc_set_mac_bssid_mask(priv, vif); + + /* + * Stop ANI only if there are no associated station interfaces. +diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c +index f6a095f8ffcd..b6d1ac9fb326 100644 +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -1290,8 +1290,9 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw, + struct ath_common *common = ath9k_hw_common(ah); + + /* +- * Use the hardware MAC address as reference, the hardware uses it +- * together with the BSSID mask when matching addresses. ++ * Pick the MAC address of the first interface as the new hardware ++ * MAC address. The hardware will use it together with the BSSID mask ++ * when matching addresses. + */ + memset(iter_data, 0, sizeof(*iter_data)); + iter_data->hw_macaddr = common->macaddr; +diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c +index 67f9430ee197..5c1379c43d1a 100644 +--- a/drivers/net/wireless/rtlwifi/pci.c ++++ b/drivers/net/wireless/rtlwifi/pci.c +@@ -678,6 +678,8 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) + }; + int index = rtlpci->rx_ring[rx_queue_idx].idx; + ++ if (rtlpci->driver_is_goingto_unload) ++ return; + /*RX NORMAL PKT */ + while (count--) { + /*rx descriptor */ +@@ -1553,6 +1555,7 @@ static void rtl_pci_stop(struct ieee80211_hw *hw) + */ + set_hal_stop(rtlhal); + ++ rtlpci->driver_is_goingto_unload = true; + rtlpriv->cfg->ops->disable_interrupt(hw); + cancel_work_sync(&rtlpriv->works.lps_leave_work); + +@@ -1570,7 +1573,6 @@ static void rtl_pci_stop(struct ieee80211_hw *hw) + ppsc->rfchange_inprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flags); + +- rtlpci->driver_is_goingto_unload = true; + rtlpriv->cfg->ops->hw_disable(hw); + /* some things are not needed if firmware not available */ + if (!rtlpriv->max_fw_size) +diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c +index 333c8d012b0e..3f93c47d50bb 100644 +--- a/drivers/tty/serial/pmac_zilog.c ++++ b/drivers/tty/serial/pmac_zilog.c +@@ -2051,6 +2051,9 @@ static int __init pmz_console_init(void) + /* Probe ports */ + pmz_probe(); + ++ if (pmz_ports_count == 0) ++ return -ENODEV; ++ + /* TODO: Autoprobe console based on OF */ + /* pmz_console.index = i; */ + register_console(&pmz_console); +diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c +index 1434ee9ecb31..e5fa34e5423f 100644 +--- a/drivers/usb/class/cdc-wdm.c ++++ b/drivers/usb/class/cdc-wdm.c +@@ -822,13 +822,11 @@ static int wdm_manage_power(struct usb_interface *intf, int on) + { + /* need autopm_get/put here to ensure the usbcore sees the new value */ + int rv = usb_autopm_get_interface(intf); +- if (rv < 0) +- goto err; + + intf->needs_remote_wakeup = on; +- usb_autopm_put_interface(intf); +-err: +- return rv; ++ if (!rv) ++ usb_autopm_put_interface(intf); ++ return 0; + } + + static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) +diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c +index 664deb63807c..546177fa7cfe 100644 +--- a/drivers/usb/serial/generic.c ++++ b/drivers/usb/serial/generic.c +@@ -223,14 +223,7 @@ retry: + return result; + } + +- /* Try sending off another urb, unless in irq context (in which case +- * there will be no free urb). */ +- if (!in_irq()) +- goto retry; +- +- clear_bit_unlock(USB_SERIAL_WRITE_BUSY, &port->flags); +- +- return 0; ++ goto retry; /* try sending off another urb */ + } + + /** +diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c +index bb01881cb1f2..9fdc0513fb4c 100644 +--- a/fs/ceph/addr.c ++++ b/fs/ceph/addr.c +@@ -213,9 +213,13 @@ static int readpage_nounlock(struct file *filp, struct page *page) + if (err < 0) { + SetPageError(page); + goto out; +- } else if (err < PAGE_CACHE_SIZE) { ++ } else { ++ if (err < PAGE_CACHE_SIZE) { + /* zero fill remainder of page */ +- zero_user_segment(page, err, PAGE_CACHE_SIZE); ++ zero_user_segment(page, err, PAGE_CACHE_SIZE); ++ } else { ++ flush_dcache_page(page); ++ } + } + SetPageUptodate(page); + +diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c +index cf1b9e043b08..ae3ca035bad3 100644 +--- a/fs/ceph/mds_client.c ++++ b/fs/ceph/mds_client.c +@@ -609,6 +609,8 @@ static void __unregister_request(struct ceph_mds_client *mdsc, + req->r_unsafe_dir = NULL; + } + ++ complete_all(&req->r_safe_completion); ++ + ceph_mdsc_put_request(req); + } + +@@ -1815,8 +1817,11 @@ static int __do_request(struct ceph_mds_client *mdsc, + int mds = -1; + int err = -EAGAIN; + +- if (req->r_err || req->r_got_result) ++ if (req->r_err || req->r_got_result) { ++ if (req->r_aborted) ++ __unregister_request(mdsc, req); + goto out; ++ } + + if (req->r_timeout && + time_after_eq(jiffies, req->r_started + req->r_timeout)) { +@@ -2129,7 +2134,6 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) + if (head->safe) { + req->r_got_safe = true; + __unregister_request(mdsc, req); +- complete_all(&req->r_safe_completion); + + if (req->r_got_unsafe) { + /* +diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c +index b9a3726ea048..c883561e9b61 100644 +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -317,8 +317,10 @@ static int ext4_valid_extent(struct inode *inode, struct ext4_extent *ext) + { + ext4_fsblk_t block = ext4_ext_pblock(ext); + int len = ext4_ext_get_actual_len(ext); ++ ext4_lblk_t lblock = le32_to_cpu(ext->ee_block); ++ ext4_lblk_t last = lblock + len - 1; + +- if (len == 0) ++ if (lblock > last) + return 0; + return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, len); + } +@@ -344,11 +346,26 @@ static int ext4_valid_extent_entries(struct inode *inode, + if (depth == 0) { + /* leaf entries */ + struct ext4_extent *ext = EXT_FIRST_EXTENT(eh); ++ struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es; ++ ext4_fsblk_t pblock = 0; ++ ext4_lblk_t lblock = 0; ++ ext4_lblk_t prev = 0; ++ int len = 0; + while (entries) { + if (!ext4_valid_extent(inode, ext)) + return 0; ++ ++ /* Check for overlapping extents */ ++ lblock = le32_to_cpu(ext->ee_block); ++ len = ext4_ext_get_actual_len(ext); ++ if ((lblock <= prev) && prev) { ++ pblock = ext4_ext_pblock(ext); ++ es->s_last_error_block = cpu_to_le64(pblock); ++ return 0; ++ } + ext++; + entries--; ++ prev = lblock + len - 1; + } + } else { + struct ext4_extent_idx *ext_idx = EXT_FIRST_INDEX(eh); +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index 878484256a6f..2941ee6ef24f 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -3326,6 +3326,9 @@ static void ext4_mb_pa_callback(struct rcu_head *head) + { + struct ext4_prealloc_space *pa; + pa = container_of(head, struct ext4_prealloc_space, u.pa_rcu); ++ ++ BUG_ON(atomic_read(&pa->pa_count)); ++ BUG_ON(pa->pa_deleted == 0); + kmem_cache_free(ext4_pspace_cachep, pa); + } + +@@ -3339,11 +3342,13 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac, + ext4_group_t grp; + ext4_fsblk_t grp_blk; + +- if (!atomic_dec_and_test(&pa->pa_count) || pa->pa_free != 0) +- return; +- + /* in this short window concurrent discard can set pa_deleted */ + spin_lock(&pa->pa_lock); ++ if (!atomic_dec_and_test(&pa->pa_count) || pa->pa_free != 0) { ++ spin_unlock(&pa->pa_lock); ++ return; ++ } ++ + if (pa->pa_deleted == 1) { + spin_unlock(&pa->pa_lock); + return; +diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c +index 9b2ff0e851b1..40bd9999250b 100644 +--- a/fs/gfs2/aops.c ++++ b/fs/gfs2/aops.c +@@ -1012,6 +1012,7 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb, + { + struct file *file = iocb->ki_filp; + struct inode *inode = file->f_mapping->host; ++ struct address_space *mapping = inode->i_mapping; + struct gfs2_inode *ip = GFS2_I(inode); + struct gfs2_holder gh; + int rv; +@@ -1032,6 +1033,35 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb, + if (rv != 1) + goto out; /* dio not valid, fall back to buffered i/o */ + ++ /* ++ * Now since we are holding a deferred (CW) lock at this point, you ++ * might be wondering why this is ever needed. There is a case however ++ * where we've granted a deferred local lock against a cached exclusive ++ * glock. That is ok provided all granted local locks are deferred, but ++ * it also means that it is possible to encounter pages which are ++ * cached and possibly also mapped. So here we check for that and sort ++ * them out ahead of the dio. The glock state machine will take care of ++ * everything else. ++ * ++ * If in fact the cached glock state (gl->gl_state) is deferred (CW) in ++ * the first place, mapping->nr_pages will always be zero. ++ */ ++ if (mapping->nrpages) { ++ loff_t lstart = offset & (PAGE_CACHE_SIZE - 1); ++ loff_t len = iov_length(iov, nr_segs); ++ loff_t end = PAGE_ALIGN(offset + len) - 1; ++ ++ rv = 0; ++ if (len == 0) ++ goto out; ++ if (test_and_clear_bit(GIF_SW_PAGED, &ip->i_flags)) ++ unmap_shared_mapping_range(ip->i_inode.i_mapping, offset, len); ++ rv = filemap_write_and_wait_range(mapping, lstart, end); ++ if (rv) ++ return rv; ++ truncate_inode_pages_range(mapping, lstart, end); ++ } ++ + rv = __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, + offset, nr_segs, gfs2_get_block_direct, + NULL, NULL, 0); +diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c +index 6f3a18f9e176..c0c529dc34aa 100644 +--- a/fs/gfs2/ops_fstype.c ++++ b/fs/gfs2/ops_fstype.c +@@ -1298,8 +1298,18 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags, + if (IS_ERR(s)) + goto error_bdev; + +- if (s->s_root) ++ if (s->s_root) { ++ /* ++ * s_umount nests inside bd_mutex during ++ * __invalidate_device(). blkdev_put() acquires ++ * bd_mutex and can't be called under s_umount. Drop ++ * s_umount temporarily. This is safe as we're ++ * holding an active reference. ++ */ ++ up_write(&s->s_umount); + blkdev_put(bdev, mode); ++ down_write(&s->s_umount); ++ } + + memset(&args, 0, sizeof(args)); + args.ar_quota = GFS2_QUOTA_DEFAULT; +diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c +index f5671271b5ba..f512c690d38e 100644 +--- a/fs/jbd2/transaction.c ++++ b/fs/jbd2/transaction.c +@@ -1126,7 +1126,10 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh) + * once a transaction -bzzz + */ + jh->b_modified = 1; +- J_ASSERT_JH(jh, handle->h_buffer_credits > 0); ++ if (handle->h_buffer_credits <= 0) { ++ ret = -ENOSPC; ++ goto out_unlock_bh; ++ } + handle->h_buffer_credits--; + } + +@@ -1209,7 +1212,6 @@ out_unlock_bh: + jbd2_journal_put_journal_head(jh); + out: + JBUFFER_TRACE(jh, "exit"); +- WARN_ON(ret); /* All errors are bugs, so dump the stack */ + return ret; + } + +diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h +index 1a13caac89d9..757f98066d6b 100644 +--- a/include/drm/drm_pciids.h ++++ b/include/drm/drm_pciids.h +@@ -544,7 +544,7 @@ + {0x1002, 0x9645, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO2|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9647, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP},\ + {0x1002, 0x9648, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP},\ +- {0x1002, 0x9649, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP},\ ++ {0x1002, 0x9649, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO2|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP},\ + {0x1002, 0x964a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x964b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x964c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ +diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c +index 09acaa15161d..2f9ac8ff1e80 100644 +--- a/kernel/sched/debug.c ++++ b/kernel/sched/debug.c +@@ -215,6 +215,14 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) + SEQ_printf(m, " .%-30s: %d\n", "load_tg", + atomic_read(&cfs_rq->tg->load_weight)); + #endif ++#ifdef CONFIG_CFS_BANDWIDTH ++ SEQ_printf(m, " .%-30s: %d\n", "tg->cfs_bandwidth.timer_active", ++ cfs_rq->tg->cfs_bandwidth.timer_active); ++ SEQ_printf(m, " .%-30s: %d\n", "throttled", ++ cfs_rq->throttled); ++ SEQ_printf(m, " .%-30s: %d\n", "throttle_count", ++ cfs_rq->throttle_count); ++#endif + + print_cfs_group_stats(m, cpu, cfs_rq->tg); + #endif +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 33c8b6038002..efe9253bd235 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -1655,6 +1655,8 @@ static void throttle_cfs_rq(struct cfs_rq *cfs_rq) + cfs_rq->throttled_timestamp = rq->clock; + raw_spin_lock(&cfs_b->lock); + list_add_tail_rcu(&cfs_rq->throttled_list, &cfs_b->throttled_cfs_rq); ++ if (!cfs_b->timer_active) ++ __start_cfs_bandwidth(cfs_b); + raw_spin_unlock(&cfs_b->lock); + } + +diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c +index ead0336007be..580d05b1784d 100644 +--- a/kernel/sched/rt.c ++++ b/kernel/sched/rt.c +@@ -942,6 +942,13 @@ inc_rt_prio_smp(struct rt_rq *rt_rq, int prio, int prev_prio) + { + struct rq *rq = rq_of_rt_rq(rt_rq); + ++#ifdef CONFIG_RT_GROUP_SCHED ++ /* ++ * Change rq's cpupri only if rt_rq is the top queue. ++ */ ++ if (&rq->rt != rt_rq) ++ return; ++#endif + if (rq->online && prio < prev_prio) + cpupri_set(&rq->rd->cpupri, rq->cpu, prio); + } +@@ -951,6 +958,13 @@ dec_rt_prio_smp(struct rt_rq *rt_rq, int prio, int prev_prio) + { + struct rq *rq = rq_of_rt_rq(rt_rq); + ++#ifdef CONFIG_RT_GROUP_SCHED ++ /* ++ * Change rq's cpupri only if rt_rq is the top queue. ++ */ ++ if (&rq->rt != rt_rq) ++ return; ++#endif + if (rq->online && rt_rq->highest_prio.curr != prev_prio) + cpupri_set(&rq->rd->cpupri, rq->cpu, rt_rq->highest_prio.curr); + } +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index 8c8169bf5020..f0e76e93aee5 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -688,7 +688,7 @@ static int ftrace_profile_init(void) + int cpu; + int ret = 0; + +- for_each_online_cpu(cpu) { ++ for_each_possible_cpu(cpu) { + ret = ftrace_profile_init_cpu(cpu); + if (ret) + break; +diff --git a/mm/rmap.c b/mm/rmap.c +index bfca52c96999..f02c862fab69 100644 +--- a/mm/rmap.c ++++ b/mm/rmap.c +@@ -623,7 +623,11 @@ pte_t *__page_check_address(struct page *page, struct mm_struct *mm, + spinlock_t *ptl; + + if (unlikely(PageHuge(page))) { ++ /* when pud is not present, pte will be NULL */ + pte = huge_pte_offset(mm, address); ++ if (!pte) ++ return NULL; ++ + ptl = &mm->page_table_lock; + goto check; + } +diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c +index 617a310025b1..60549a4a2f98 100644 +--- a/net/wireless/radiotap.c ++++ b/net/wireless/radiotap.c +@@ -122,6 +122,10 @@ int ieee80211_radiotap_iterator_init( + /* find payload start allowing for extended bitmap(s) */ + + if (iterator->_bitmap_shifter & (1<_arg - ++ (unsigned long)iterator->_rtheader + sizeof(uint32_t) > ++ (unsigned long)iterator->_max_length) ++ return -EINVAL; + while (get_unaligned_le32(iterator->_arg) & + (1 << IEEE80211_RADIOTAP_EXT)) { + iterator->_arg += sizeof(uint32_t); +diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c +index d32db4140aa0..9f6380ec1305 100644 +--- a/security/selinux/hooks.c ++++ b/security/selinux/hooks.c +@@ -3720,7 +3720,7 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid) + u32 nlbl_sid; + u32 nlbl_type; + +- selinux_skb_xfrm_sid(skb, &xfrm_sid); ++ selinux_xfrm_skb_sid(skb, &xfrm_sid); + selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid); + + err = security_net_peersid_resolve(nlbl_sid, nlbl_type, xfrm_sid, sid); +@@ -4240,8 +4240,10 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) + } + err = avc_has_perm(sk_sid, peer_sid, SECCLASS_PEER, + PEER__RECV, &ad); +- if (err) ++ if (err) { + selinux_netlbl_err(skb, err, 0); ++ return err; ++ } + } + + if (secmark_active) { +@@ -4727,22 +4729,32 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, + * as fast and as clean as possible. */ + if (!selinux_policycap_netpeer) + return selinux_ip_postroute_compat(skb, ifindex, family); ++ ++ secmark_active = selinux_secmark_enabled(); ++ peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled(); ++ if (!secmark_active && !peerlbl_active) ++ return NF_ACCEPT; ++ ++ sk = skb->sk; ++ + #ifdef CONFIG_XFRM + /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec + * packet transformation so allow the packet to pass without any checks + * since we'll have another chance to perform access control checks + * when the packet is on it's final way out. + * NOTE: there appear to be some IPv6 multicast cases where skb->dst +- * is NULL, in this case go ahead and apply access control. */ +- if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL) ++ * is NULL, in this case go ahead and apply access control. ++ * is NULL, in this case go ahead and apply access control. ++ * NOTE: if this is a local socket (skb->sk != NULL) that is in the ++ * TCP listening state we cannot wait until the XFRM processing ++ * is done as we will miss out on the SA label if we do; ++ * unfortunately, this means more work, but it is only once per ++ * connection. */ ++ if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL && ++ !(sk != NULL && sk->sk_state == TCP_LISTEN)) + return NF_ACCEPT; + #endif +- secmark_active = selinux_secmark_enabled(); +- peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled(); +- if (!secmark_active && !peerlbl_active) +- return NF_ACCEPT; + +- sk = skb->sk; + if (sk == NULL) { + /* Without an associated socket the packet is either coming + * from the kernel or it is being forwarded; check the packet +@@ -4770,6 +4782,25 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, + struct sk_security_struct *sksec = sk->sk_security; + if (selinux_skb_peerlbl_sid(skb, family, &skb_sid)) + return NF_DROP; ++ /* At this point, if the returned skb peerlbl is SECSID_NULL ++ * and the packet has been through at least one XFRM ++ * transformation then we must be dealing with the "final" ++ * form of labeled IPsec packet; since we've already applied ++ * all of our access controls on this packet we can safely ++ * pass the packet. */ ++ if (skb_sid == SECSID_NULL) { ++ switch (family) { ++ case PF_INET: ++ if (IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) ++ return NF_ACCEPT; ++ break; ++ case PF_INET6: ++ if (IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) ++ return NF_ACCEPT; ++ default: ++ return NF_DROP_ERR(-ECONNREFUSED); ++ } ++ } + if (selinux_conn_sid(sksec->sid, skb_sid, &peer_sid)) + return NF_DROP; + secmark_perm = PACKET__SEND; +@@ -5443,11 +5474,11 @@ static int selinux_setprocattr(struct task_struct *p, + /* Check for ptracing, and update the task SID if ok. + Otherwise, leave SID unchanged and fail. */ + ptsid = 0; +- task_lock(p); ++ rcu_read_lock(); + tracer = ptrace_parent(p); + if (tracer) + ptsid = task_sid(tracer); +- task_unlock(p); ++ rcu_read_unlock(); + + if (tracer) { + error = avc_has_perm(ptsid, sid, SECCLASS_PROCESS, +diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h +index c220f314709c..d1c980cee5d1 100644 +--- a/security/selinux/include/xfrm.h ++++ b/security/selinux/include/xfrm.h +@@ -47,6 +47,7 @@ int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb, + int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, + struct common_audit_data *ad, u8 proto); + int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall); ++int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid); + + static inline void selinux_xfrm_notify_policyload(void) + { +@@ -79,12 +80,12 @@ static inline int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int + static inline void selinux_xfrm_notify_policyload(void) + { + } +-#endif + +-static inline void selinux_skb_xfrm_sid(struct sk_buff *skb, u32 *sid) ++static inline int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid) + { +- int err = selinux_xfrm_decode_session(skb, sid, 0); +- BUG_ON(err); ++ *sid = SECSID_NULL; ++ return 0; + } ++#endif + + #endif /* _SELINUX_XFRM_H_ */ +diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c +index 8ab295154517..1552b910d9e2 100644 +--- a/security/selinux/xfrm.c ++++ b/security/selinux/xfrm.c +@@ -152,21 +152,13 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy * + return rc; + } + +-/* +- * LSM hook implementation that checks and/or returns the xfrm sid for the +- * incoming packet. +- */ +- +-int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall) ++static int selinux_xfrm_skb_sid_ingress(struct sk_buff *skb, ++ u32 *sid, int ckall) + { +- struct sec_path *sp; ++ struct sec_path *sp = skb->sp; + + *sid = SECSID_NULL; + +- if (skb == NULL) +- return 0; +- +- sp = skb->sp; + if (sp) { + int i, sid_set = 0; + +@@ -190,6 +182,45 @@ int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall) + return 0; + } + ++static u32 selinux_xfrm_skb_sid_egress(struct sk_buff *skb) ++{ ++ struct dst_entry *dst = skb_dst(skb); ++ struct xfrm_state *x; ++ ++ if (dst == NULL) ++ return SECSID_NULL; ++ x = dst->xfrm; ++ if (x == NULL || !selinux_authorizable_xfrm(x)) ++ return SECSID_NULL; ++ ++ return x->security->ctx_sid; ++} ++ ++/* ++ * LSM hook implementation that checks and/or returns the xfrm sid for the ++ * incoming packet. ++ */ ++ ++int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall) ++{ ++ if (skb == NULL) { ++ *sid = SECSID_NULL; ++ return 0; ++ } ++ return selinux_xfrm_skb_sid_ingress(skb, sid, ckall); ++} ++ ++int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid) ++{ ++ int rc; ++ ++ rc = selinux_xfrm_skb_sid_ingress(skb, sid, 0); ++ if (rc == 0 && *sid == SECSID_NULL) ++ *sid = selinux_xfrm_skb_sid_egress(skb); ++ ++ return rc; ++} ++ + /* + * Security blob allocation for xfrm_policy and xfrm_state + * CTX does not have a meaningful value on input +diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c +index 4d18941178e6..370fc56d2de7 100644 +--- a/sound/core/pcm_lib.c ++++ b/sound/core/pcm_lib.c +@@ -1847,6 +1847,8 @@ static int wait_for_avail(struct snd_pcm_substream *substream, + case SNDRV_PCM_STATE_DISCONNECTED: + err = -EBADFD; + goto _endloop; ++ case SNDRV_PCM_STATE_PAUSED: ++ continue; + } + if (!tout) { + snd_printd("%s write error (DMA or IRQ trouble?)\n", +diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c +index 4e190b5950ba..c93e360b6706 100644 +--- a/sound/soc/codecs/wm8904.c ++++ b/sound/soc/codecs/wm8904.c +@@ -1456,7 +1456,7 @@ static int wm8904_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_B: +- aif1 |= WM8904_AIF_LRCLK_INV; ++ aif1 |= 0x3 | WM8904_AIF_LRCLK_INV; + case SND_SOC_DAIFMT_DSP_A: + aif1 |= 0x3; + break; +diff --git a/tools/power/cpupower/utils/cpupower-set.c b/tools/power/cpupower/utils/cpupower-set.c +index dc4de3762111..bcf1d2f0b791 100644 +--- a/tools/power/cpupower/utils/cpupower-set.c ++++ b/tools/power/cpupower/utils/cpupower-set.c +@@ -18,9 +18,9 @@ + #include "helpers/bitmask.h" + + static struct option set_opts[] = { +- { .name = "perf-bias", .has_arg = optional_argument, .flag = NULL, .val = 'b'}, +- { .name = "sched-mc", .has_arg = optional_argument, .flag = NULL, .val = 'm'}, +- { .name = "sched-smt", .has_arg = optional_argument, .flag = NULL, .val = 's'}, ++ { .name = "perf-bias", .has_arg = required_argument, .flag = NULL, .val = 'b'}, ++ { .name = "sched-mc", .has_arg = required_argument, .flag = NULL, .val = 'm'}, ++ { .name = "sched-smt", .has_arg = required_argument, .flag = NULL, .val = 's'}, + { }, + }; + diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.76-77.patch b/patch/kernel/sun8i-default/0001-patch-3.4.76-77.patch new file mode 100644 index 000000000..986e04319 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.76-77.patch @@ -0,0 +1,743 @@ +diff --git a/Makefile b/Makefile +index 8045c75414ae..bbdd7ab3e0e3 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 76 ++SUBLEVEL = 77 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c +index a53a5a3c3c2e..f01ad2992a20 100644 +--- a/arch/arm/kernel/traps.c ++++ b/arch/arm/kernel/traps.c +@@ -37,7 +37,13 @@ + + #include "signal.h" + +-static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" }; ++static const char *handler[]= { ++ "prefetch abort", ++ "data abort", ++ "address exception", ++ "interrupt", ++ "undefined instruction", ++}; + + void *vectors_page; + +diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c +index 8c6202bb6aeb..9c19b45db36d 100644 +--- a/arch/arm/mach-shmobile/board-mackerel.c ++++ b/arch/arm/mach-shmobile/board-mackerel.c +@@ -422,7 +422,7 @@ static struct platform_device lcdc_device = { + .resource = lcdc_resources, + .dev = { + .platform_data = &lcdc_info, +- .coherent_dma_mask = ~0, ++ .coherent_dma_mask = DMA_BIT_MASK(32), + }, + }; + +@@ -498,7 +498,7 @@ static struct platform_device hdmi_lcdc_device = { + .id = 1, + .dev = { + .platform_data = &hdmi_lcdc_info, +- .coherent_dma_mask = ~0, ++ .coherent_dma_mask = DMA_BIT_MASK(32), + }, + }; + +diff --git a/arch/x86/include/asm/fpu-internal.h b/arch/x86/include/asm/fpu-internal.h +index 92e05b6c84f8..a65708f2f015 100644 +--- a/arch/x86/include/asm/fpu-internal.h ++++ b/arch/x86/include/asm/fpu-internal.h +@@ -266,12 +266,13 @@ static inline int restore_fpu_checking(struct task_struct *tsk) + /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception + is pending. Clear the x87 state here by setting it to fixed + values. "m" is a random variable that should be in L1 */ +- alternative_input( +- ASM_NOP8 ASM_NOP2, +- "emms\n\t" /* clear stack tags */ +- "fildl %P[addr]", /* set F?P to defined value */ +- X86_FEATURE_FXSAVE_LEAK, +- [addr] "m" (tsk->thread.fpu.has_fpu)); ++ if (unlikely(static_cpu_has(X86_FEATURE_FXSAVE_LEAK))) { ++ asm volatile( ++ "fnclex\n\t" ++ "emms\n\t" ++ "fildl %P[addr]" /* set F?P to defined value */ ++ : : [addr] "m" (tsk->thread.fpu.has_fpu)); ++ } + + return fpu_restore_checking(&tsk->thread.fpu); + } +diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c +index 3551ad82ba8f..650286be8da1 100644 +--- a/drivers/net/ethernet/broadcom/tg3.c ++++ b/drivers/net/ethernet/broadcom/tg3.c +@@ -14671,6 +14671,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) + /* Clear this out for sanity. */ + tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0); + ++ /* Clear TG3PCI_REG_BASE_ADDR to prevent hangs. */ ++ tw32(TG3PCI_REG_BASE_ADDR, 0); ++ + pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE, + &pci_state_reg); + if ((pci_state_reg & PCISTATE_CONV_PCI_MODE) == 0 && +diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c +index 4ebbe6f609d0..5699105112d3 100644 +--- a/drivers/net/ethernet/calxeda/xgmac.c ++++ b/drivers/net/ethernet/calxeda/xgmac.c +@@ -1776,7 +1776,7 @@ static int xgmac_probe(struct platform_device *pdev) + if (device_can_wakeup(priv->device)) + priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */ + +- ndev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA; ++ ndev->hw_features = NETIF_F_SG | NETIF_F_HIGHDMA; + if (readl(priv->base + XGMAC_DMA_HW_FEATURE) & DMA_HW_FEAT_TXCOESEL) + ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | + NETIF_F_RXCSUM; +diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c +index f4d2da0db1b1..8b3da6eb5bc4 100644 +--- a/drivers/net/ethernet/ibm/ehea/ehea_main.c ++++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c +@@ -3029,7 +3029,7 @@ static struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, + + dev->hw_features = NETIF_F_SG | NETIF_F_TSO + | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX | NETIF_F_LRO; +- dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO ++ dev->features = NETIF_F_SG | NETIF_F_TSO + | NETIF_F_HIGHDMA | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX + | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER + | NETIF_F_RXCSUM; +diff --git a/drivers/net/ethernet/tehuti/tehuti.c b/drivers/net/ethernet/tehuti/tehuti.c +index ad973ffc9ff3..32f0bcd5e30d 100644 +--- a/drivers/net/ethernet/tehuti/tehuti.c ++++ b/drivers/net/ethernet/tehuti/tehuti.c +@@ -1995,7 +1995,6 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO + | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | + NETIF_F_HW_VLAN_FILTER | NETIF_F_RXCSUM +- /*| NETIF_F_FRAGLIST */ + ; + ndev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | + NETIF_F_TSO | NETIF_F_HW_VLAN_TX; +diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c +index 5e5b791f12e9..d240c0624d46 100644 +--- a/drivers/net/ethernet/xilinx/ll_temac_main.c ++++ b/drivers/net/ethernet/xilinx/ll_temac_main.c +@@ -1026,7 +1026,7 @@ static int __devinit temac_of_probe(struct platform_device *op) + dev_set_drvdata(&op->dev, ndev); + SET_NETDEV_DEV(ndev, &op->dev); + ndev->flags &= ~IFF_MULTICAST; /* clear multicast */ +- ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST; ++ ndev->features = NETIF_F_SG; + ndev->netdev_ops = &temac_netdev_ops; + ndev->ethtool_ops = &temac_ethtool_ops; + #if 0 +diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +index 9c365e192a31..fde716dec196 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c ++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +@@ -1494,7 +1494,7 @@ static int __devinit axienet_of_probe(struct platform_device *op) + + SET_NETDEV_DEV(ndev, &op->dev); + ndev->flags &= ~IFF_MULTICAST; /* clear multicast */ +- ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST; ++ ndev->features = NETIF_F_SG; + ndev->netdev_ops = &axienet_netdev_ops; + ndev->ethtool_ops = &axienet_ethtool_ops; + +diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c +index a4a3516b6bbf..3b3a7e07bbf1 100644 +--- a/drivers/net/hamradio/hdlcdrv.c ++++ b/drivers/net/hamradio/hdlcdrv.c +@@ -571,6 +571,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 (bi.data.calibrate > INT_MAX / s->par.bitrate) ++ return -EINVAL; + s->hdlctx.calibrate = bi.data.calibrate * s->par.bitrate / 16; + return 0; + +diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c +index 5a6412ecce73..d8faeb628aa7 100644 +--- a/drivers/net/hamradio/yam.c ++++ b/drivers/net/hamradio/yam.c +@@ -1058,6 +1058,7 @@ static int yam_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) + break; + + case SIOCYAMGCFG: ++ memset(&yi, 0, sizeof(yi)); + yi.cfg.mask = 0xffffffff; + yi.cfg.iobase = yp->iobase; + yi.cfg.irq = yp->irq; +diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c +index 2d59138db7f3..a6ed38284134 100644 +--- a/drivers/net/hyperv/netvsc_drv.c ++++ b/drivers/net/hyperv/netvsc_drv.c +@@ -321,7 +321,6 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu) + return -EINVAL; + + nvdev->start_remove = true; +- cancel_delayed_work_sync(&ndevctx->dwork); + cancel_work_sync(&ndevctx->work); + netif_tx_disable(ndev); + rndis_filter_device_remove(hdev); +diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c +index 77ce8b2bee6d..f5b9de48bb82 100644 +--- a/drivers/net/macvtap.c ++++ b/drivers/net/macvtap.c +@@ -797,11 +797,10 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, + const struct sk_buff *skb, + const struct iovec *iv, int len) + { +- struct macvlan_dev *vlan; + int ret; + int vnet_hdr_len = 0; + int vlan_offset = 0; +- int copied; ++ int copied, total; + + if (q->flags & IFF_VNET_HDR) { + struct virtio_net_hdr vnet_hdr; +@@ -816,7 +815,8 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, + if (memcpy_toiovecend(iv, (void *)&vnet_hdr, 0, sizeof(vnet_hdr))) + return -EFAULT; + } +- copied = vnet_hdr_len; ++ total = copied = vnet_hdr_len; ++ total += skb->len; + + if (!vlan_tx_tag_present(skb)) + len = min_t(int, skb->len, len); +@@ -831,6 +831,7 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, + + vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); + len = min_t(int, skb->len + VLAN_HLEN, len); ++ total += VLAN_HLEN; + + copy = min_t(int, vlan_offset, len); + ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy); +@@ -848,16 +849,9 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, + } + + ret = skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len); +- copied += len; + + done: +- rcu_read_lock_bh(); +- vlan = rcu_dereference_bh(q->vlan); +- if (vlan) +- macvlan_count_rx(vlan, copied - vnet_hdr_len, ret == 0, 0); +- rcu_read_unlock_bh(); +- +- return ret ? ret : copied; ++ return ret ? ret : total; + } + + static ssize_t macvtap_do_read(struct macvtap_queue *q, struct kiocb *iocb, +@@ -911,7 +905,9 @@ static ssize_t macvtap_aio_read(struct kiocb *iocb, const struct iovec *iv, + } + + ret = macvtap_do_read(q, iocb, iv, len, file->f_flags & O_NONBLOCK); +- ret = min_t(ssize_t, ret, len); /* XXX copied from tun.c. Why? */ ++ ret = min_t(ssize_t, ret, len); ++ if (ret > 0) ++ iocb->ki_pos = ret; + out: + return ret; + } +diff --git a/drivers/net/tun.c b/drivers/net/tun.c +index 194f8798b7ed..5b1a1b51fdb0 100644 +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -903,6 +903,8 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv, + + ret = tun_do_read(tun, iocb, iv, len, file->f_flags & O_NONBLOCK); + ret = min_t(ssize_t, ret, len); ++ if (ret > 0) ++ iocb->ki_pos = ret; + out: + tun_put(tun); + return ret; +diff --git a/include/linux/net.h b/include/linux/net.h +index 45232814fc03..ff8097592f1d 100644 +--- a/include/linux/net.h ++++ b/include/linux/net.h +@@ -215,7 +215,7 @@ struct proto_ops { + int offset, size_t size, int flags); + ssize_t (*splice_read)(struct socket *sock, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, unsigned int flags); +- void (*set_peek_off)(struct sock *sk, int val); ++ int (*set_peek_off)(struct sock *sk, int val); + }; + + #define DECLARE_SOCKADDR(type, dst, src) \ +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index dc6c6878700c..5b465010f102 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -1702,6 +1702,15 @@ static inline int dev_parse_header(const struct sk_buff *skb, + return dev->header_ops->parse(skb, haddr); + } + ++static inline int dev_rebuild_header(struct sk_buff *skb) ++{ ++ const struct net_device *dev = skb->dev; ++ ++ if (!dev->header_ops || !dev->header_ops->rebuild) ++ return 0; ++ return dev->header_ops->rebuild(skb); ++} ++ + typedef int gifconf_func_t(struct net_device * dev, char __user * bufptr, int len); + extern int register_gifconf(unsigned int family, gifconf_func_t * gifconf); + static inline int unregister_gifconf(unsigned int family) +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index 4b6c546774b2..3a5b31796edf 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -7906,7 +7906,12 @@ static int tg_set_cfs_bandwidth(struct task_group *tg, u64 period, u64 quota) + + runtime_enabled = quota != RUNTIME_INF; + runtime_was_enabled = cfs_b->quota != RUNTIME_INF; +- account_cfs_bandwidth_used(runtime_enabled, runtime_was_enabled); ++ /* ++ * If we need to toggle cfs_bandwidth_used, off->on must occur ++ * before making related changes, and on->off must occur afterwards ++ */ ++ if (runtime_enabled && !runtime_was_enabled) ++ cfs_bandwidth_usage_inc(); + raw_spin_lock_irq(&cfs_b->lock); + cfs_b->period = ns_to_ktime(period); + cfs_b->quota = quota; +@@ -7932,6 +7937,8 @@ static int tg_set_cfs_bandwidth(struct task_group *tg, u64 period, u64 quota) + unthrottle_cfs_rq(cfs_rq); + raw_spin_unlock_irq(&rq->lock); + } ++ if (runtime_was_enabled && !runtime_enabled) ++ cfs_bandwidth_usage_dec(); + out_unlock: + mutex_unlock(&cfs_constraints_mutex); + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index efe9253bd235..363df3702c20 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -1393,13 +1393,14 @@ static inline bool cfs_bandwidth_used(void) + return static_key_false(&__cfs_bandwidth_used); + } + +-void account_cfs_bandwidth_used(int enabled, int was_enabled) ++void cfs_bandwidth_usage_inc(void) + { +- /* only need to count groups transitioning between enabled/!enabled */ +- if (enabled && !was_enabled) +- static_key_slow_inc(&__cfs_bandwidth_used); +- else if (!enabled && was_enabled) +- static_key_slow_dec(&__cfs_bandwidth_used); ++ static_key_slow_inc(&__cfs_bandwidth_used); ++} ++ ++void cfs_bandwidth_usage_dec(void) ++{ ++ static_key_slow_dec(&__cfs_bandwidth_used); + } + #else /* HAVE_JUMP_LABEL */ + static bool cfs_bandwidth_used(void) +@@ -1407,7 +1408,8 @@ static bool cfs_bandwidth_used(void) + return true; + } + +-void account_cfs_bandwidth_used(int enabled, int was_enabled) {} ++void cfs_bandwidth_usage_inc(void) {} ++void cfs_bandwidth_usage_dec(void) {} + #endif /* HAVE_JUMP_LABEL */ + + /* +@@ -1769,6 +1771,13 @@ static int do_sched_cfs_period_timer(struct cfs_bandwidth *cfs_b, int overrun) + if (idle) + goto out_unlock; + ++ /* ++ * if we have relooped after returning idle once, we need to update our ++ * status as actually running, so that other cpus doing ++ * __start_cfs_bandwidth will stop trying to cancel us. ++ */ ++ cfs_b->timer_active = 1; ++ + __refill_cfs_bandwidth_runtime(cfs_b); + + if (!throttled) { +@@ -1829,7 +1838,13 @@ static const u64 min_bandwidth_expiration = 2 * NSEC_PER_MSEC; + /* how long we wait to gather additional slack before distributing */ + static const u64 cfs_bandwidth_slack_period = 5 * NSEC_PER_MSEC; + +-/* are we near the end of the current quota period? */ ++/* ++ * Are we near the end of the current quota period? ++ * ++ * Requires cfs_b->lock for hrtimer_expires_remaining to be safe against the ++ * hrtimer base being cleared by __hrtimer_start_range_ns. In the case of ++ * migrate_hrtimers, base is never cleared, so we are fine. ++ */ + static int runtime_refresh_within(struct cfs_bandwidth *cfs_b, u64 min_expire) + { + struct hrtimer *refresh_timer = &cfs_b->period_timer; +@@ -1905,10 +1920,12 @@ static void do_sched_cfs_slack_timer(struct cfs_bandwidth *cfs_b) + u64 expires; + + /* confirm we're still not at a refresh boundary */ +- if (runtime_refresh_within(cfs_b, min_bandwidth_expiration)) ++ raw_spin_lock(&cfs_b->lock); ++ if (runtime_refresh_within(cfs_b, min_bandwidth_expiration)) { ++ raw_spin_unlock(&cfs_b->lock); + return; ++ } + +- raw_spin_lock(&cfs_b->lock); + if (cfs_b->quota != RUNTIME_INF && cfs_b->runtime > slice) { + runtime = cfs_b->runtime; + cfs_b->runtime = 0; +@@ -2033,11 +2050,11 @@ void __start_cfs_bandwidth(struct cfs_bandwidth *cfs_b) + * (timer_active==0 becomes visible before the hrtimer call-back + * terminates). In either case we ensure that it's re-programmed + */ +- while (unlikely(hrtimer_active(&cfs_b->period_timer))) { ++ while (unlikely(hrtimer_active(&cfs_b->period_timer)) && ++ hrtimer_try_to_cancel(&cfs_b->period_timer) < 0) { ++ /* bounce the lock to allow do_sched_cfs_period_timer to run */ + raw_spin_unlock(&cfs_b->lock); +- /* ensure cfs_b->lock is available while we wait */ +- hrtimer_cancel(&cfs_b->period_timer); +- ++ cpu_relax(); + raw_spin_lock(&cfs_b->lock); + /* if someone else restarted the timer then we're done */ + if (cfs_b->timer_active) +@@ -5453,7 +5470,8 @@ void init_tg_cfs_entry(struct task_group *tg, struct cfs_rq *cfs_rq, + se->cfs_rq = parent->my_q; + + se->my_q = cfs_rq; +- update_load_set(&se->load, 0); ++ /* guarantee group entities always have weight */ ++ update_load_set(&se->load, NICE_0_LOAD); + se->parent = parent; + } + +diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h +index acfa7017eb0a..4e2bd6c32da7 100644 +--- a/kernel/sched/sched.h ++++ b/kernel/sched/sched.h +@@ -1140,7 +1140,8 @@ extern void init_cfs_rq(struct cfs_rq *cfs_rq); + extern void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq); + extern void unthrottle_offline_cfs_rqs(struct rq *rq); + +-extern void account_cfs_bandwidth_used(int enabled, int was_enabled); ++extern void cfs_bandwidth_usage_inc(void); ++extern void cfs_bandwidth_usage_dec(void); + + #ifdef CONFIG_NO_HZ + enum rq_nohz_flag_bits { +diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c +index 8f453927cc51..c2029f732126 100644 +--- a/net/8021q/vlan_dev.c ++++ b/net/8021q/vlan_dev.c +@@ -525,6 +525,23 @@ static const struct header_ops vlan_header_ops = { + .parse = eth_header_parse, + }; + ++static int vlan_passthru_hard_header(struct sk_buff *skb, struct net_device *dev, ++ unsigned short type, ++ const void *daddr, const void *saddr, ++ unsigned int len) ++{ ++ struct vlan_dev_priv *vlan = vlan_dev_priv(dev); ++ struct net_device *real_dev = vlan->real_dev; ++ ++ return dev_hard_header(skb, real_dev, type, daddr, saddr, len); ++} ++ ++static const struct header_ops vlan_passthru_header_ops = { ++ .create = vlan_passthru_hard_header, ++ .rebuild = dev_rebuild_header, ++ .parse = eth_header_parse, ++}; ++ + static const struct net_device_ops vlan_netdev_ops; + + static int vlan_dev_init(struct net_device *dev) +@@ -564,7 +581,7 @@ static int vlan_dev_init(struct net_device *dev) + + dev->needed_headroom = real_dev->needed_headroom; + if (real_dev->features & NETIF_F_HW_VLAN_TX) { +- dev->header_ops = real_dev->header_ops; ++ dev->header_ops = &vlan_passthru_header_ops; + dev->hard_header_len = real_dev->hard_header_len; + } else { + dev->header_ops = &vlan_header_ops; +diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c +index ca670d96bae7..cef202a94112 100644 +--- a/net/bridge/br_multicast.c ++++ b/net/bridge/br_multicast.c +@@ -1744,7 +1744,7 @@ int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val) + u32 old; + struct net_bridge_mdb_htable *mdb; + +- spin_lock(&br->multicast_lock); ++ spin_lock_bh(&br->multicast_lock); + if (!netif_running(br->dev)) + goto unlock; + +@@ -1776,7 +1776,7 @@ rollback: + } + + unlock: +- spin_unlock(&br->multicast_lock); ++ spin_unlock_bh(&br->multicast_lock); + + return err; + } +diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c +index b856f87e63d2..1d9a52929bad 100644 +--- a/net/core/drop_monitor.c ++++ b/net/core/drop_monitor.c +@@ -61,7 +61,6 @@ static struct genl_family net_drop_monitor_family = { + .hdrsize = 0, + .name = "NET_DM", + .version = 2, +- .maxattr = NET_DM_CMD_MAX, + }; + + static DEFINE_PER_CPU(struct per_cpu_dm_data, dm_cpu_data); +diff --git a/net/core/sock.c b/net/core/sock.c +index 561eb57f590c..832cf043a8f7 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -795,7 +795,7 @@ set_rcvbuf: + + case SO_PEEK_OFF: + if (sock->ops->set_peek_off) +- sock->ops->set_peek_off(sk, val); ++ ret = sock->ops->set_peek_off(sk, val); + else + ret = -EOPNOTSUPP; + break; +diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c +index d7b862ad4be4..5fcc8df3f179 100644 +--- a/net/ipv4/inet_diag.c ++++ b/net/ipv4/inet_diag.c +@@ -110,6 +110,10 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, + + r->id.idiag_sport = inet->inet_sport; + r->id.idiag_dport = inet->inet_dport; ++ ++ memset(&r->id.idiag_src, 0, sizeof(r->id.idiag_src)); ++ memset(&r->id.idiag_dst, 0, sizeof(r->id.idiag_dst)); ++ + r->id.idiag_src[0] = inet->inet_rcv_saddr; + r->id.idiag_dst[0] = inet->inet_daddr; + +@@ -227,12 +231,19 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, + + r->idiag_family = tw->tw_family; + r->idiag_retrans = 0; ++ + r->id.idiag_if = tw->tw_bound_dev_if; + sock_diag_save_cookie(tw, r->id.idiag_cookie); ++ + r->id.idiag_sport = tw->tw_sport; + r->id.idiag_dport = tw->tw_dport; ++ ++ memset(&r->id.idiag_src, 0, sizeof(r->id.idiag_src)); ++ memset(&r->id.idiag_dst, 0, sizeof(r->id.idiag_dst)); ++ + r->id.idiag_src[0] = tw->tw_rcv_saddr; + r->id.idiag_dst[0] = tw->tw_daddr; ++ + r->idiag_state = tw->tw_substate; + r->idiag_timer = 3; + r->idiag_expires = DIV_ROUND_UP(tmo * 1000, HZ); +@@ -714,8 +725,13 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, + + r->id.idiag_sport = inet->inet_sport; + r->id.idiag_dport = ireq->rmt_port; ++ ++ memset(&r->id.idiag_src, 0, sizeof(r->id.idiag_src)); ++ memset(&r->id.idiag_dst, 0, sizeof(r->id.idiag_dst)); ++ + r->id.idiag_src[0] = ireq->loc_addr; + r->id.idiag_dst[0] = ireq->rmt_addr; ++ + r->idiag_expires = jiffies_to_msecs(tmo); + r->idiag_rqueue = 0; + r->idiag_wqueue = 0; +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 6ac8bc29b43e..335b16fccb9d 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -2114,15 +2114,11 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, + { + struct net *net = dev_net(idev->dev); + struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, +- net->loopback_dev, 0); ++ net->loopback_dev, DST_NOCOUNT); + int err; + +- if (!rt) { +- if (net_ratelimit()) +- pr_warning("IPv6: Maximum number of routes reached," +- " consider increasing route/max_size.\n"); ++ if (!rt) + return ERR_PTR(-ENOMEM); +- } + + in6_dev_hold(idev); + +diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c +index df08d7779e1d..1c2dc50c9b44 100644 +--- a/net/llc/af_llc.c ++++ b/net/llc/af_llc.c +@@ -716,7 +716,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, + unsigned long cpu_flags; + size_t copied = 0; + u32 peek_seq = 0; +- u32 *seq; ++ u32 *seq, skb_len; + unsigned long used; + int target; /* Read at least this many bytes */ + long timeo; +@@ -814,6 +814,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, + } + continue; + found_ok_skb: ++ skb_len = skb->len; + /* Ok so how much can we use? */ + used = skb->len - offset; + if (len < used) +@@ -846,7 +847,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, + } + + /* Partial read */ +- if (used + offset < skb->len) ++ if (used + offset < skb_len) + continue; + } while (len > 0); + +diff --git a/net/rds/ib.c b/net/rds/ib.c +index b4c8b0022fee..ba2dffeff608 100644 +--- a/net/rds/ib.c ++++ b/net/rds/ib.c +@@ -338,7 +338,8 @@ static int rds_ib_laddr_check(__be32 addr) + ret = rdma_bind_addr(cm_id, (struct sockaddr *)&sin); + /* due to this, we will claim to support iWARP devices unless we + check node_type. */ +- if (ret || cm_id->device->node_type != RDMA_NODE_IB_CA) ++ if (ret || !cm_id->device || ++ cm_id->device->node_type != RDMA_NODE_IB_CA) + ret = -EADDRNOTAVAIL; + + rdsdebug("addr %pI4 ret %d node type %d\n", +diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c +index e59094981175..37be6e226d1b 100644 +--- a/net/rds/ib_send.c ++++ b/net/rds/ib_send.c +@@ -552,9 +552,8 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, + && rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) { + rds_cong_map_updated(conn->c_fcong, ~(u64) 0); + scat = &rm->data.op_sg[sg]; +- ret = sizeof(struct rds_header) + RDS_CONG_MAP_BYTES; +- ret = min_t(int, ret, scat->length - conn->c_xmit_data_off); +- return ret; ++ ret = max_t(int, RDS_CONG_MAP_BYTES, scat->length); ++ return sizeof(struct rds_header) + ret; + } + + /* FIXME we may overallocate here */ +diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c +index ce5f5b934ea1..bde7d69b440d 100644 +--- a/net/rose/af_rose.c ++++ b/net/rose/af_rose.c +@@ -1257,6 +1257,7 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock, + + if (msg->msg_name) { + struct sockaddr_rose *srose; ++ struct full_sockaddr_rose *full_srose = msg->msg_name; + + memset(msg->msg_name, 0, sizeof(struct full_sockaddr_rose)); + srose = msg->msg_name; +@@ -1264,18 +1265,9 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock, + srose->srose_addr = rose->dest_addr; + srose->srose_call = rose->dest_call; + srose->srose_ndigis = rose->dest_ndigis; +- if (msg->msg_namelen >= sizeof(struct full_sockaddr_rose)) { +- struct full_sockaddr_rose *full_srose = (struct full_sockaddr_rose *)msg->msg_name; +- for (n = 0 ; n < rose->dest_ndigis ; n++) +- full_srose->srose_digis[n] = rose->dest_digis[n]; +- msg->msg_namelen = sizeof(struct full_sockaddr_rose); +- } else { +- if (rose->dest_ndigis >= 1) { +- srose->srose_ndigis = 1; +- srose->srose_digi = rose->dest_digis[0]; +- } +- msg->msg_namelen = sizeof(struct sockaddr_rose); +- } ++ for (n = 0 ; n < rose->dest_ndigis ; n++) ++ full_srose->srose_digis[n] = rose->dest_digis[n]; ++ msg->msg_namelen = sizeof(struct full_sockaddr_rose); + } + + skb_free_datagram(sk, skb); +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 0540dd9b0387..c0a81a50bd4e 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -524,13 +524,17 @@ static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *, + static int unix_seqpacket_recvmsg(struct kiocb *, struct socket *, + struct msghdr *, size_t, int); + +-static void unix_set_peek_off(struct sock *sk, int val) ++static int unix_set_peek_off(struct sock *sk, int val) + { + struct unix_sock *u = unix_sk(sk); + +- mutex_lock(&u->readlock); ++ if (mutex_lock_interruptible(&u->readlock)) ++ return -EINTR; ++ + sk->sk_peek_off = val; + mutex_unlock(&u->readlock); ++ ++ return 0; + } + + +@@ -708,7 +712,9 @@ static int unix_autobind(struct socket *sock) + int err; + unsigned int retries = 0; + +- mutex_lock(&u->readlock); ++ err = mutex_lock_interruptible(&u->readlock); ++ if (err) ++ return err; + + err = 0; + if (u->addr) +@@ -841,7 +847,9 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) + goto out; + addr_len = err; + +- mutex_lock(&u->readlock); ++ err = mutex_lock_interruptible(&u->readlock); ++ if (err) ++ goto out; + + err = -EINVAL; + if (u->addr) diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.77-78.patch b/patch/kernel/sun8i-default/0001-patch-3.4.77-78.patch new file mode 100644 index 000000000..35942e52a --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.77-78.patch @@ -0,0 +1,416 @@ +diff --git a/Makefile b/Makefile +index bbdd7ab3e0e3..e891990fbf1c 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 77 ++SUBLEVEL = 78 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/x86/kernel/cpu/perf_event_amd_ibs.c b/arch/x86/kernel/cpu/perf_event_amd_ibs.c +index 3b8a2d30d14e..ea34253cb9c6 100644 +--- a/arch/x86/kernel/cpu/perf_event_amd_ibs.c ++++ b/arch/x86/kernel/cpu/perf_event_amd_ibs.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + + #include + +@@ -209,6 +210,18 @@ out: + return ret; + } + ++static void ibs_eilvt_setup(void) ++{ ++ /* ++ * Force LVT offset assignment for family 10h: The offsets are ++ * not assigned by the BIOS for this family, so the OS is ++ * responsible for doing it. If the OS assignment fails, fall ++ * back to BIOS settings and try to setup this. ++ */ ++ if (boot_cpu_data.x86 == 0x10) ++ force_ibs_eilvt_setup(); ++} ++ + static inline int get_ibs_lvt_offset(void) + { + u64 val; +@@ -244,6 +257,36 @@ static void clear_APIC_ibs(void *dummy) + setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_FIX, 1); + } + ++#ifdef CONFIG_PM ++ ++static int perf_ibs_suspend(void) ++{ ++ clear_APIC_ibs(NULL); ++ return 0; ++} ++ ++static void perf_ibs_resume(void) ++{ ++ ibs_eilvt_setup(); ++ setup_APIC_ibs(NULL); ++} ++ ++static struct syscore_ops perf_ibs_syscore_ops = { ++ .resume = perf_ibs_resume, ++ .suspend = perf_ibs_suspend, ++}; ++ ++static void perf_ibs_pm_init(void) ++{ ++ register_syscore_ops(&perf_ibs_syscore_ops); ++} ++ ++#else ++ ++static inline void perf_ibs_pm_init(void) { } ++ ++#endif ++ + static int __cpuinit + perf_ibs_cpu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) + { +@@ -270,18 +313,12 @@ static __init int amd_ibs_init(void) + if (!caps) + return -ENODEV; /* ibs not supported by the cpu */ + +- /* +- * Force LVT offset assignment for family 10h: The offsets are +- * not assigned by the BIOS for this family, so the OS is +- * responsible for doing it. If the OS assignment fails, fall +- * back to BIOS settings and try to setup this. +- */ +- if (boot_cpu_data.x86 == 0x10) +- force_ibs_eilvt_setup(); ++ ibs_eilvt_setup(); + + if (!ibs_eilvt_valid()) + goto out; + ++ perf_ibs_pm_init(); + get_online_cpus(); + ibs_caps = caps; + /* make ibs_caps visible to other cpus: */ +diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c +index 858432287ab6..2bf03a99c2f9 100644 +--- a/arch/x86/kvm/lapic.c ++++ b/arch/x86/kvm/lapic.c +@@ -1278,14 +1278,12 @@ void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu) + void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu) + { + u32 data; +- void *vapic; + + if (!irqchip_in_kernel(vcpu->kvm) || !vcpu->arch.apic->vapic_addr) + return; + +- vapic = kmap_atomic(vcpu->arch.apic->vapic_page); +- data = *(u32 *)(vapic + offset_in_page(vcpu->arch.apic->vapic_addr)); +- kunmap_atomic(vapic); ++ kvm_read_guest_cached(vcpu->kvm, &vcpu->arch.apic->vapic_cache, &data, ++ sizeof(u32)); + + apic_set_tpr(vcpu->arch.apic, data & 0xff); + } +@@ -1295,7 +1293,6 @@ void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu) + u32 data, tpr; + int max_irr, max_isr; + struct kvm_lapic *apic; +- void *vapic; + + if (!irqchip_in_kernel(vcpu->kvm) || !vcpu->arch.apic->vapic_addr) + return; +@@ -1310,17 +1307,24 @@ void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu) + max_isr = 0; + data = (tpr & 0xff) | ((max_isr & 0xf0) << 8) | (max_irr << 24); + +- vapic = kmap_atomic(vcpu->arch.apic->vapic_page); +- *(u32 *)(vapic + offset_in_page(vcpu->arch.apic->vapic_addr)) = data; +- kunmap_atomic(vapic); ++ kvm_write_guest_cached(vcpu->kvm, &vcpu->arch.apic->vapic_cache, &data, ++ sizeof(u32)); + } + +-void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr) ++int kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr) + { + if (!irqchip_in_kernel(vcpu->kvm)) +- return; ++ return -EINVAL; ++ ++ if (vapic_addr) { ++ if (kvm_gfn_to_hva_cache_init(vcpu->kvm, ++ &vcpu->arch.apic->vapic_cache, ++ vapic_addr, sizeof(u32))) ++ return -EINVAL; ++ } + + vcpu->arch.apic->vapic_addr = vapic_addr; ++ return 0; + } + + int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data) +diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h +index 6f4ce2575d09..6aec0714398e 100644 +--- a/arch/x86/kvm/lapic.h ++++ b/arch/x86/kvm/lapic.h +@@ -15,7 +15,7 @@ struct kvm_lapic { + bool irr_pending; + void *regs; + gpa_t vapic_addr; +- struct page *vapic_page; ++ struct gfn_to_hva_cache vapic_cache; + }; + int kvm_create_lapic(struct kvm_vcpu *vcpu); + void kvm_free_lapic(struct kvm_vcpu *vcpu); +@@ -46,7 +46,7 @@ int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu); + u64 kvm_get_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu); + void kvm_set_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu, u64 data); + +-void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr); ++int kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr); + void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu); + void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu); + +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 3663e0b38976..4b1be290f6e3 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -2728,8 +2728,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp, + r = -EFAULT; + if (copy_from_user(&va, argp, sizeof va)) + goto out; +- r = 0; +- kvm_lapic_set_vapic_addr(vcpu, va.vapic_addr); ++ r = kvm_lapic_set_vapic_addr(vcpu, va.vapic_addr); + break; + } + case KVM_X86_SETUP_MCE: { +@@ -5075,33 +5074,6 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu) + !kvm_event_needs_reinjection(vcpu); + } + +-static void vapic_enter(struct kvm_vcpu *vcpu) +-{ +- struct kvm_lapic *apic = vcpu->arch.apic; +- struct page *page; +- +- if (!apic || !apic->vapic_addr) +- return; +- +- page = gfn_to_page(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT); +- +- vcpu->arch.apic->vapic_page = page; +-} +- +-static void vapic_exit(struct kvm_vcpu *vcpu) +-{ +- struct kvm_lapic *apic = vcpu->arch.apic; +- int idx; +- +- if (!apic || !apic->vapic_addr) +- return; +- +- idx = srcu_read_lock(&vcpu->kvm->srcu); +- kvm_release_page_dirty(apic->vapic_page); +- mark_page_dirty(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT); +- srcu_read_unlock(&vcpu->kvm->srcu, idx); +-} +- + static void update_cr8_intercept(struct kvm_vcpu *vcpu) + { + int max_irr, tpr; +@@ -5385,7 +5357,6 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) + } + + vcpu->srcu_idx = srcu_read_lock(&kvm->srcu); +- vapic_enter(vcpu); + + r = 1; + while (r > 0) { +@@ -5442,8 +5413,6 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) + + srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx); + +- vapic_exit(vcpu); +- + return r; + } + +diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c +index 0f52799973d4..fac07d3ae4f3 100644 +--- a/drivers/hwmon/coretemp.c ++++ b/drivers/hwmon/coretemp.c +@@ -53,7 +53,7 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius"); + + #define BASE_SYSFS_ATTR_NO 2 /* Sysfs Base attr no for coretemp */ + #define NUM_REAL_CORES 32 /* Number of Real cores per cpu */ +-#define CORETEMP_NAME_LENGTH 17 /* String Length of attrs */ ++#define CORETEMP_NAME_LENGTH 19 /* String Length of attrs */ + #define MAX_CORE_ATTRS 4 /* Maximum no of basic attrs */ + #define TOTAL_ATTRS (MAX_CORE_ATTRS + 1) + #define MAX_CORE_DATA (NUM_REAL_CORES + BASE_SYSFS_ATTR_NO) +diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c +index 99a102d186ce..67a8393e3f86 100644 +--- a/drivers/md/raid10.c ++++ b/drivers/md/raid10.c +@@ -1117,7 +1117,7 @@ read_again: + /* Could not read all from this device, so we will + * need another r10_bio. + */ +- sectors_handled = (r10_bio->sectors + max_sectors ++ sectors_handled = (r10_bio->sector + max_sectors + - bio->bi_sector); + r10_bio->sectors = max_sectors; + spin_lock_irq(&conf->device_lock); +@@ -1125,7 +1125,7 @@ read_again: + bio->bi_phys_segments = 2; + else + bio->bi_phys_segments++; +- spin_unlock(&conf->device_lock); ++ spin_unlock_irq(&conf->device_lock); + /* Cannot call generic_make_request directly + * as that will be queued in __generic_make_request + * and subsequent mempool_alloc might block +@@ -2943,10 +2943,6 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, + if (j == conf->copies) { + /* Cannot recover, so abort the recovery or + * record a bad block */ +- put_buf(r10_bio); +- if (rb2) +- atomic_dec(&rb2->remaining); +- r10_bio = rb2; + if (any_working) { + /* problem is that there are bad blocks + * on other device(s) +@@ -2978,6 +2974,10 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, + mirror->recovery_disabled + = mddev->recovery_disabled; + } ++ put_buf(r10_bio); ++ if (rb2) ++ atomic_dec(&rb2->remaining); ++ r10_bio = rb2; + break; + } + } +diff --git a/drivers/staging/comedi/drivers/cb_pcidio.c b/drivers/staging/comedi/drivers/cb_pcidio.c +index 8f3215239a15..453ea2d57346 100644 +--- a/drivers/staging/comedi/drivers/cb_pcidio.c ++++ b/drivers/staging/comedi/drivers/cb_pcidio.c +@@ -56,10 +56,6 @@ struct pcidio_board { + const char *name; /* name of the board */ + int dev_id; + int n_8255; /* number of 8255 chips on board */ +- +- /* indices of base address regions */ +- int pcicontroler_badrindex; +- int dioregs_badrindex; + }; + + static const struct pcidio_board pcidio_boards[] = { +@@ -67,22 +63,16 @@ static const struct pcidio_board pcidio_boards[] = { + .name = "pci-dio24", + .dev_id = 0x0028, + .n_8255 = 1, +- .pcicontroler_badrindex = 1, +- .dioregs_badrindex = 2, + }, + { + .name = "pci-dio24h", + .dev_id = 0x0014, + .n_8255 = 1, +- .pcicontroler_badrindex = 1, +- .dioregs_badrindex = 2, + }, + { + .name = "pci-dio48h", + .dev_id = 0x000b, + .n_8255 = 2, +- .pcicontroler_badrindex = 0, +- .dioregs_badrindex = 1, + }, + }; + +@@ -239,10 +229,15 @@ found: + if (comedi_pci_enable(pcidev, thisboard->name)) + return -EIO; + +- devpriv->dio_reg_base +- = ++ /* ++ * Use PCI BAR 2 region if non-zero length, else use PCI BAR 1 region. ++ * PCI BAR 1 is only used for older PCI-DIO48H boards. At some point ++ * the PCI-DIO48H was redesigned to use the same PCI interface chip ++ * (and same PCI BAR region) as the other boards. ++ */ ++ devpriv->dio_reg_base = + pci_resource_start(devpriv->pci_dev, +- pcidio_boards[index].dioregs_badrindex); ++ (pci_resource_len(pcidev, 2) ? 2 : 1)); + + /* + * Allocate the subdevice structures. alloc_subdevice() is a +diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c +index 88e11fb346b6..d4ca8925f017 100644 +--- a/fs/nilfs2/segment.c ++++ b/fs/nilfs2/segment.c +@@ -1436,17 +1436,19 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci, + + nilfs_clear_logs(&sci->sc_segbufs); + +- err = nilfs_segctor_extend_segments(sci, nilfs, nadd); +- if (unlikely(err)) +- return err; +- + if (sci->sc_stage.flags & NILFS_CF_SUFREED) { + err = nilfs_sufile_cancel_freev(nilfs->ns_sufile, + sci->sc_freesegs, + sci->sc_nfreesegs, + NULL); + WARN_ON(err); /* do not happen */ ++ sci->sc_stage.flags &= ~NILFS_CF_SUFREED; + } ++ ++ err = nilfs_segctor_extend_segments(sci, nilfs, nadd); ++ if (unlikely(err)) ++ return err; ++ + nadd = min_t(int, nadd << 1, SC_MAX_SEGDELTA); + sci->sc_stage = prev_stage; + } +diff --git a/mm/memory-failure.c b/mm/memory-failure.c +index d86fb2057354..7e95698e4139 100644 +--- a/mm/memory-failure.c ++++ b/mm/memory-failure.c +@@ -1447,10 +1447,18 @@ static int soft_offline_huge_page(struct page *page, int flags) + return ret; + } + done: +- if (!PageHWPoison(hpage)) +- atomic_long_add(1 << compound_trans_order(hpage), &mce_bad_pages); +- set_page_hwpoison_huge_page(hpage); +- dequeue_hwpoisoned_huge_page(hpage); ++ /* overcommit hugetlb page will be freed to buddy */ ++ if (PageHuge(hpage)) { ++ if (!PageHWPoison(hpage)) ++ atomic_long_add(1 << compound_trans_order(hpage), ++ &mce_bad_pages); ++ set_page_hwpoison_huge_page(hpage); ++ dequeue_hwpoisoned_huge_page(hpage); ++ } else { ++ SetPageHWPoison(page); ++ atomic_long_inc(&mce_bad_pages); ++ } ++ + /* keep elevated page count for bad page */ + return ret; + } diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.78-79.patch b/patch/kernel/sun8i-default/0001-patch-3.4.78-79.patch new file mode 100644 index 000000000..bfd21e5ab --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.78-79.patch @@ -0,0 +1,1305 @@ +diff --git a/Makefile b/Makefile +index e891990fbf1c..7e9c23f19fe4 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 78 ++SUBLEVEL = 79 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/arm/mach-at91/sam9_smc.c b/arch/arm/mach-at91/sam9_smc.c +index 99a0a1d2b7dc..b26156bf15db 100644 +--- a/arch/arm/mach-at91/sam9_smc.c ++++ b/arch/arm/mach-at91/sam9_smc.c +@@ -101,7 +101,7 @@ static void sam9_smc_cs_read(void __iomem *base, + /* Pulse register */ + val = __raw_readl(base + AT91_SMC_PULSE); + +- config->nwe_setup = val & AT91_SMC_NWEPULSE; ++ config->nwe_pulse = val & AT91_SMC_NWEPULSE; + config->ncs_write_pulse = (val & AT91_SMC_NCS_WRPULSE) >> 8; + config->nrd_pulse = (val & AT91_SMC_NRDPULSE) >> 16; + config->ncs_read_pulse = (val & AT91_SMC_NCS_RDPULSE) >> 24; +diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c +index 92c6b008dd2b..b4437e8a7a8f 100644 +--- a/arch/powerpc/kernel/cacheinfo.c ++++ b/arch/powerpc/kernel/cacheinfo.c +@@ -788,6 +788,9 @@ static void remove_cache_dir(struct cache_dir *cache_dir) + { + remove_index_dirs(cache_dir); + ++ /* Remove cache dir from sysfs */ ++ kobject_del(cache_dir->kobj); ++ + kobject_put(cache_dir->kobj); + + kfree(cache_dir); +diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c +index 2bf03a99c2f9..578613da251e 100644 +--- a/arch/x86/kvm/lapic.c ++++ b/arch/x86/kvm/lapic.c +@@ -538,7 +538,8 @@ static u32 apic_get_tmcct(struct kvm_lapic *apic) + ASSERT(apic != NULL); + + /* if initial count is 0, current count should also be 0 */ +- if (apic_get_reg(apic, APIC_TMICT) == 0) ++ if (apic_get_reg(apic, APIC_TMICT) == 0 || ++ apic->lapic_timer.period == 0) + return 0; + + remaining = hrtimer_get_remaining(&apic->lapic_timer.timer); +diff --git a/drivers/edac/e752x_edac.c b/drivers/edac/e752x_edac.c +index 41223261ede9..b73beba0aa24 100644 +--- a/drivers/edac/e752x_edac.c ++++ b/drivers/edac/e752x_edac.c +@@ -1145,9 +1145,11 @@ static int e752x_get_devs(struct pci_dev *pdev, int dev_idx, + pvt->bridge_ck = pci_get_device(PCI_VENDOR_ID_INTEL, + pvt->dev_info->err_dev, pvt->bridge_ck); + +- if (pvt->bridge_ck == NULL) ++ if (pvt->bridge_ck == NULL) { + pvt->bridge_ck = pci_scan_single_device(pdev->bus, + PCI_DEVFN(0, 1)); ++ pci_dev_get(pvt->bridge_ck); ++ } + + if (pvt->bridge_ck == NULL) { + e752x_printk(KERN_ERR, "error reporting device not found:" +diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c +index 6155c8b261a9..3aed841ce84b 100644 +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -1805,6 +1805,7 @@ static void raid5_end_write_request(struct bio *bi, int error) + set_bit(R5_MadeGoodRepl, &sh->dev[i].flags); + } else { + if (!uptodate) { ++ set_bit(STRIPE_DEGRADED, &sh->state); + set_bit(WriteErrorSeen, &rdev->flags); + set_bit(R5_WriteError, &sh->dev[i].flags); + if (!test_and_set_bit(WantReplacement, &rdev->flags)) +diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +index e45b8b6d6848..0f05cef53455 100644 +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +@@ -71,6 +71,7 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata, + struct sk_buff *skb = tx_buf->skb; + u16 bd_idx = TX_BD(tx_buf->first_bd), new_cons; + int nbd; ++ u16 split_bd_len = 0; + + /* prefetch skb end pointer to speedup dev_kfree_skb() */ + prefetch(&skb->end); +@@ -78,10 +79,7 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata, + DP(NETIF_MSG_TX_DONE, "fp[%d]: pkt_idx %d buff @(%p)->skb %p\n", + txdata->txq_index, idx, tx_buf, skb); + +- /* unmap first bd */ + tx_start_bd = &txdata->tx_desc_ring[bd_idx].start_bd; +- dma_unmap_single(&bp->pdev->dev, BD_UNMAP_ADDR(tx_start_bd), +- BD_UNMAP_LEN(tx_start_bd), DMA_TO_DEVICE); + + + nbd = le16_to_cpu(tx_start_bd->nbd) - 1; +@@ -100,12 +98,19 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata, + --nbd; + bd_idx = TX_BD(NEXT_TX_IDX(bd_idx)); + +- /* ...and the TSO split header bd since they have no mapping */ ++ /* TSO headers+data bds share a common mapping. See bnx2x_tx_split() */ + if (tx_buf->flags & BNX2X_TSO_SPLIT_BD) { ++ tx_data_bd = &txdata->tx_desc_ring[bd_idx].reg_bd; ++ split_bd_len = BD_UNMAP_LEN(tx_data_bd); + --nbd; + bd_idx = TX_BD(NEXT_TX_IDX(bd_idx)); + } + ++ /* unmap first bd */ ++ dma_unmap_single(&bp->pdev->dev, BD_UNMAP_ADDR(tx_start_bd), ++ BD_UNMAP_LEN(tx_start_bd) + split_bd_len, ++ DMA_TO_DEVICE); ++ + /* now free frags */ + while (nbd > 0) { + +diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c +index 5fa0880e342e..60f4a51153af 100644 +--- a/drivers/net/ethernet/via/via-rhine.c ++++ b/drivers/net/ethernet/via/via-rhine.c +@@ -1601,6 +1601,7 @@ static void rhine_reset_task(struct work_struct *work) + goto out_unlock; + + napi_disable(&rp->napi); ++ netif_tx_disable(dev); + spin_lock_bh(&rp->lock); + + /* clear all descriptors */ +diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h +index 05cb5f6b8d48..46389a041cee 100644 +--- a/drivers/net/wireless/b43/b43.h ++++ b/drivers/net/wireless/b43/b43.h +@@ -719,8 +719,6 @@ enum b43_firmware_file_type { + struct b43_request_fw_context { + /* The device we are requesting the fw for. */ + struct b43_wldev *dev; +- /* a completion event structure needed if this call is asynchronous */ +- struct completion fw_load_complete; + /* a pointer to the firmware object */ + const struct firmware *blob; + /* The type of firmware to request. */ +@@ -797,6 +795,8 @@ enum { + struct b43_wldev { + struct b43_bus_dev *dev; + struct b43_wl *wl; ++ /* a completion event structure needed if this call is asynchronous */ ++ struct completion fw_load_complete; + + /* The device initialization status. + * Use b43_status() to query. */ +diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c +index f8c4499cf644..b91f55965b3a 100644 +--- a/drivers/net/wireless/b43/main.c ++++ b/drivers/net/wireless/b43/main.c +@@ -2061,6 +2061,7 @@ void b43_do_release_fw(struct b43_firmware_file *fw) + + static void b43_release_firmware(struct b43_wldev *dev) + { ++ complete(&dev->fw_load_complete); + b43_do_release_fw(&dev->fw.ucode); + b43_do_release_fw(&dev->fw.pcm); + b43_do_release_fw(&dev->fw.initvals); +@@ -2086,7 +2087,7 @@ static void b43_fw_cb(const struct firmware *firmware, void *context) + struct b43_request_fw_context *ctx = context; + + ctx->blob = firmware; +- complete(&ctx->fw_load_complete); ++ complete(&ctx->dev->fw_load_complete); + } + + int b43_do_request_fw(struct b43_request_fw_context *ctx, +@@ -2133,7 +2134,7 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx, + } + if (async) { + /* do this part asynchronously */ +- init_completion(&ctx->fw_load_complete); ++ init_completion(&ctx->dev->fw_load_complete); + err = request_firmware_nowait(THIS_MODULE, 1, ctx->fwname, + ctx->dev->dev->dev, GFP_KERNEL, + ctx, b43_fw_cb); +@@ -2141,12 +2142,11 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx, + pr_err("Unable to load firmware\n"); + return err; + } +- /* stall here until fw ready */ +- wait_for_completion(&ctx->fw_load_complete); ++ wait_for_completion(&ctx->dev->fw_load_complete); + if (ctx->blob) + goto fw_ready; + /* On some ARM systems, the async request will fail, but the next sync +- * request works. For this reason, we dall through here ++ * request works. For this reason, we fall through here + */ + } + err = request_firmware(&ctx->blob, ctx->fwname, +@@ -2413,6 +2413,7 @@ error: + + static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl); + static void b43_one_core_detach(struct b43_bus_dev *dev); ++static int b43_rng_init(struct b43_wl *wl); + + static void b43_request_firmware(struct work_struct *work) + { +@@ -2459,6 +2460,10 @@ start_ieee80211: + if (err) + goto err_one_core_detach; + b43_leds_register(wl->current_dev); ++ ++ /* Register HW RNG driver */ ++ b43_rng_init(wl); ++ + goto out; + + err_one_core_detach: +@@ -4583,9 +4588,6 @@ static void b43_wireless_core_exit(struct b43_wldev *dev) + if (!dev || b43_status(dev) != B43_STAT_INITIALIZED) + return; + +- /* Unregister HW RNG driver */ +- b43_rng_exit(dev->wl); +- + b43_set_status(dev, B43_STAT_UNINIT); + + /* Stop the microcode PSM. */ +@@ -4728,9 +4730,6 @@ static int b43_wireless_core_init(struct b43_wldev *dev) + + b43_set_status(dev, B43_STAT_INITIALIZED); + +- /* Register HW RNG driver */ +- b43_rng_init(dev->wl); +- + out: + return err; + +@@ -5388,6 +5387,9 @@ static void b43_bcma_remove(struct bcma_device *core) + + b43_one_core_detach(wldev->dev); + ++ /* Unregister HW RNG driver */ ++ b43_rng_exit(wl); ++ + b43_leds_unregister(wl); + + ieee80211_free_hw(wl->hw); +@@ -5468,6 +5470,9 @@ static void b43_ssb_remove(struct ssb_device *sdev) + + b43_one_core_detach(dev); + ++ /* Unregister HW RNG driver */ ++ b43_rng_exit(wl); ++ + if (list_empty(&wl->devlist)) { + b43_leds_unregister(wl); + /* Last core on the chip unregistered. +diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c +index 2c5367884b3f..9db0f8e132e6 100644 +--- a/drivers/net/wireless/b43/xmit.c ++++ b/drivers/net/wireless/b43/xmit.c +@@ -819,10 +819,10 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) + * channel number in b43. */ + if (chanstat & B43_RX_CHAN_5GHZ) { + status.band = IEEE80211_BAND_5GHZ; +- status.freq = b43_freq_to_channel_5ghz(chanid); ++ status.freq = b43_channel_to_freq_5ghz(chanid); + } else { + status.band = IEEE80211_BAND_2GHZ; +- status.freq = b43_freq_to_channel_2ghz(chanid); ++ status.freq = b43_channel_to_freq_2ghz(chanid); + } + break; + default: +diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c +index 53696efbe155..ce7242454e95 100644 +--- a/drivers/net/wireless/b43legacy/main.c ++++ b/drivers/net/wireless/b43legacy/main.c +@@ -3915,6 +3915,7 @@ static void b43legacy_remove(struct ssb_device *dev) + * as the ieee80211 unreg will destroy the workqueue. */ + cancel_work_sync(&wldev->restart_work); + cancel_work_sync(&wl->firmware_load); ++ complete(&wldev->fw_load_complete); + + B43legacy_WARN_ON(!wl); + if (!wldev->fw.ucode) +diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c +index 278e9f957e0d..c3d325823c81 100644 +--- a/drivers/net/wireless/rtlwifi/core.c ++++ b/drivers/net/wireless/rtlwifi/core.c +@@ -175,6 +175,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, + rtlpriv->cfg->maps + [RTL_IBSS_INT_MASKS]); + } ++ mac->link_state = MAC80211_LINKED; + break; + case NL80211_IFTYPE_ADHOC: + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, +diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c +index 476342647589..bbe9a788c28b 100644 +--- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c ++++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c +@@ -85,17 +85,15 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + if (mac->act_scanning) { + tx_agc[RF90_PATH_A] = 0x3f3f3f3f; + tx_agc[RF90_PATH_B] = 0x3f3f3f3f; +- if (turbo_scanoff) { +- for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { +- tx_agc[idx1] = ppowerlevel[idx1] | +- (ppowerlevel[idx1] << 8) | +- (ppowerlevel[idx1] << 16) | +- (ppowerlevel[idx1] << 24); +- if (rtlhal->interface == INTF_USB) { +- if (tx_agc[idx1] > 0x20 && +- rtlefuse->external_pa) +- tx_agc[idx1] = 0x20; +- } ++ for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { ++ tx_agc[idx1] = ppowerlevel[idx1] | ++ (ppowerlevel[idx1] << 8) | ++ (ppowerlevel[idx1] << 16) | ++ (ppowerlevel[idx1] << 24); ++ if (rtlhal->interface == INTF_USB) { ++ if (tx_agc[idx1] > 0x20 && ++ rtlefuse->external_pa) ++ tx_agc[idx1] = 0x20; + } + } + } else { +@@ -107,7 +105,7 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + TXHIGHPWRLEVEL_LEVEL2) { + tx_agc[RF90_PATH_A] = 0x00000000; + tx_agc[RF90_PATH_B] = 0x00000000; +- } else{ ++ } else { + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + tx_agc[idx1] = ppowerlevel[idx1] | + (ppowerlevel[idx1] << 8) | +@@ -379,7 +377,12 @@ static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw, + regoffset == RTXAGC_B_MCS07_MCS04) + regoffset = 0xc98; + for (i = 0; i < 3; i++) { +- writeVal = (writeVal > 6) ? (writeVal - 6) : 0; ++ if (i != 2) ++ writeVal = (writeVal > 8) ? ++ (writeVal - 8) : 0; ++ else ++ writeVal = (writeVal > 6) ? ++ (writeVal - 6) : 0; + rtl_write_byte(rtlpriv, (u32)(regoffset + i), + (u8)writeVal); + } +diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +index 3f869c9f71ee..52a9c338fa47 100644 +--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c ++++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +@@ -306,6 +306,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = { + {RTL_USB_DEVICE(0x0bda, 0x5088, rtl92cu_hal_cfg)}, /*Thinkware-CC&C*/ + {RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ + {RTL_USB_DEVICE(0x0df6, 0x005c, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ ++ {RTL_USB_DEVICE(0x0df6, 0x0077, rtl92cu_hal_cfg)}, /*Sitecom-WLA2100V2*/ + {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ + {RTL_USB_DEVICE(0x4856, 0x0091, rtl92cu_hal_cfg)}, /*NetweeN - Feixun*/ + /* HP - Lite-On ,8188CUS Slim Combo */ +diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c +index 0cb64f50cecd..a655ae2d80d3 100644 +--- a/drivers/parport/parport_pc.c ++++ b/drivers/parport/parport_pc.c +@@ -2875,8 +2875,6 @@ enum parport_pc_pci_cards { + syba_2p_epp, + syba_1p_ecp, + titan_010l, +- titan_1284p1, +- titan_1284p2, + avlab_1p, + avlab_2p, + oxsemi_952, +@@ -2935,8 +2933,6 @@ static struct parport_pc_pci { + /* syba_2p_epp AP138B */ { 2, { { 0, 0x078 }, { 0, 0x178 }, } }, + /* syba_1p_ecp W83787 */ { 1, { { 0, 0x078 }, } }, + /* titan_010l */ { 1, { { 3, -1 }, } }, +- /* titan_1284p1 */ { 1, { { 0, 1 }, } }, +- /* titan_1284p2 */ { 2, { { 0, 1 }, { 2, 3 }, } }, + /* avlab_1p */ { 1, { { 0, 1}, } }, + /* avlab_2p */ { 2, { { 0, 1}, { 2, 3 },} }, + /* The Oxford Semi cards are unusual: 954 doesn't support ECP, +@@ -2952,8 +2948,8 @@ static struct parport_pc_pci { + /* netmos_9705 */ { 1, { { 0, -1 }, } }, + /* netmos_9715 */ { 2, { { 0, 1 }, { 2, 3 },} }, + /* netmos_9755 */ { 2, { { 0, 1 }, { 2, 3 },} }, +- /* netmos_9805 */ { 1, { { 0, -1 }, } }, +- /* netmos_9815 */ { 2, { { 0, -1 }, { 2, -1 }, } }, ++ /* netmos_9805 */ { 1, { { 0, 1 }, } }, ++ /* netmos_9815 */ { 2, { { 0, 1 }, { 2, 3 }, } }, + /* netmos_9901 */ { 1, { { 0, -1 }, } }, + /* netmos_9865 */ { 1, { { 0, -1 }, } }, + /* quatech_sppxp100 */ { 1, { { 0, 1 }, } }, +@@ -2997,8 +2993,6 @@ static const struct pci_device_id parport_pc_pci_tbl[] = { + PCI_ANY_ID, PCI_ANY_ID, 0, 0, syba_1p_ecp }, + { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_010L, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_010l }, +- { 0x9710, 0x9805, 0x1000, 0x0010, 0, 0, titan_1284p1 }, +- { 0x9710, 0x9815, 0x1000, 0x0020, 0, 0, titan_1284p2 }, + /* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/ + /* AFAVLAB_TK9902 */ + { 0x14db, 0x2120, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1p}, +diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c +index fdacfcebd175..0076feae0ce3 100644 +--- a/drivers/platform/x86/hp_accel.c ++++ b/drivers/platform/x86/hp_accel.c +@@ -77,6 +77,7 @@ static inline void delayed_sysfs_set(struct led_classdev *led_cdev, + static struct acpi_device_id lis3lv02d_device_ids[] = { + {"HPQ0004", 0}, /* HP Mobile Data Protection System PNP */ + {"HPQ6000", 0}, /* HP Mobile Data Protection System PNP */ ++ {"HPQ6007", 0}, /* HP Mobile Data Protection System PNP */ + {"", 0}, + }; + MODULE_DEVICE_TABLE(acpi, lis3lv02d_device_ids); +diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c +index 404fd10ddb21..e991c61eef1d 100644 +--- a/drivers/scsi/bfa/bfad.c ++++ b/drivers/scsi/bfa/bfad.c +@@ -1615,7 +1615,7 @@ out: + static u32 * + bfad_load_fwimg(struct pci_dev *pdev) + { +- if (pdev->device == BFA_PCI_DEVICE_ID_CT2) { ++ if (bfa_asic_id_ct2(pdev->device)) { + if (bfi_image_ct2_size == 0) + bfad_read_firmware(pdev, &bfi_image_ct2, + &bfi_image_ct2_size, BFAD_FW_FILE_CT2); +@@ -1625,12 +1625,14 @@ bfad_load_fwimg(struct pci_dev *pdev) + bfad_read_firmware(pdev, &bfi_image_ct, + &bfi_image_ct_size, BFAD_FW_FILE_CT); + return bfi_image_ct; +- } else { ++ } else if (bfa_asic_id_cb(pdev->device)) { + if (bfi_image_cb_size == 0) + bfad_read_firmware(pdev, &bfi_image_cb, + &bfi_image_cb_size, BFAD_FW_FILE_CB); + return bfi_image_cb; + } ++ ++ return NULL; + } + + static void +diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c +index 7b3ae00ac54a..1b1bf38e8839 100644 +--- a/drivers/staging/rtl8712/usb_intf.c ++++ b/drivers/staging/rtl8712/usb_intf.c +@@ -361,6 +361,10 @@ static u8 key_2char2num(u8 hch, u8 lch) + return (hex_to_bin(hch) << 4) | hex_to_bin(lch); + } + ++static const struct device_type wlan_type = { ++ .name = "wlan", ++}; ++ + /* + * drv_init() - a device potentially for us + * +@@ -396,6 +400,7 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf, + padapter->pusb_intf = pusb_intf; + usb_set_intfdata(pusb_intf, pnetdev); + SET_NETDEV_DEV(pnetdev, &pusb_intf->dev); ++ pnetdev->dev.type = &wlan_type; + /* step 2. */ + padapter->dvobj_init = &r8712_usb_dvobj_init; + padapter->dvobj_deinit = &r8712_usb_dvobj_deinit; +diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c +index 858e2a8ee260..4034281efb8e 100644 +--- a/drivers/staging/vt6656/baseband.c ++++ b/drivers/staging/vt6656/baseband.c +@@ -1634,7 +1634,6 @@ BBvUpdatePreEDThreshold( + + if( bScanning ) + { // need Max sensitivity //RSSI -69, -70,.... +- if(pDevice->byBBPreEDIndex == 0) break; + pDevice->byBBPreEDIndex = 0; + ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9) + ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x30); //CR206(0xCE) +@@ -1777,7 +1776,6 @@ BBvUpdatePreEDThreshold( + + if( bScanning ) + { // need Max sensitivity //RSSI -69, -70, ... +- if(pDevice->byBBPreEDIndex == 0) break; + pDevice->byBBPreEDIndex = 0; + ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9) + ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x24); //CR206(0xCE) +@@ -1929,7 +1927,6 @@ BBvUpdatePreEDThreshold( + case RF_VT3342A0: //RobertYu:20060627, testing table + if( bScanning ) + { // need Max sensitivity //RSSI -67, -68, ... +- if(pDevice->byBBPreEDIndex == 0) break; + pDevice->byBBPreEDIndex = 0; + ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9) + ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x38); //CR206(0xCE) +diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c +index 486c5dd45016..8d9100321474 100644 +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -50,7 +50,7 @@ + static LIST_HEAD(g_tiqn_list); + static LIST_HEAD(g_np_list); + static DEFINE_SPINLOCK(tiqn_lock); +-static DEFINE_SPINLOCK(np_lock); ++static DEFINE_MUTEX(np_lock); + + static struct idr tiqn_idr; + struct idr sess_idr; +@@ -262,6 +262,9 @@ int iscsit_deaccess_np(struct iscsi_np *np, struct iscsi_portal_group *tpg) + return 0; + } + ++/* ++ * Called with mutex np_lock held ++ */ + static struct iscsi_np *iscsit_get_np( + struct __kernel_sockaddr_storage *sockaddr, + int network_transport) +@@ -272,11 +275,10 @@ static struct iscsi_np *iscsit_get_np( + int ip_match = 0; + u16 port; + +- spin_lock_bh(&np_lock); + list_for_each_entry(np, &g_np_list, np_list) { +- spin_lock(&np->np_thread_lock); ++ spin_lock_bh(&np->np_thread_lock); + if (np->np_thread_state != ISCSI_NP_THREAD_ACTIVE) { +- spin_unlock(&np->np_thread_lock); ++ spin_unlock_bh(&np->np_thread_lock); + continue; + } + +@@ -309,13 +311,11 @@ static struct iscsi_np *iscsit_get_np( + * while iscsi_tpg_add_network_portal() is called. + */ + np->np_exports++; +- spin_unlock(&np->np_thread_lock); +- spin_unlock_bh(&np_lock); ++ spin_unlock_bh(&np->np_thread_lock); + return np; + } +- spin_unlock(&np->np_thread_lock); ++ spin_unlock_bh(&np->np_thread_lock); + } +- spin_unlock_bh(&np_lock); + + return NULL; + } +@@ -329,16 +329,22 @@ struct iscsi_np *iscsit_add_np( + struct sockaddr_in6 *sock_in6; + struct iscsi_np *np; + int ret; ++ ++ mutex_lock(&np_lock); ++ + /* + * Locate the existing struct iscsi_np if already active.. + */ + np = iscsit_get_np(sockaddr, network_transport); +- if (np) ++ if (np) { ++ mutex_unlock(&np_lock); + return np; ++ } + + np = kzalloc(sizeof(struct iscsi_np), GFP_KERNEL); + if (!np) { + pr_err("Unable to allocate memory for struct iscsi_np\n"); ++ mutex_unlock(&np_lock); + return ERR_PTR(-ENOMEM); + } + +@@ -361,6 +367,7 @@ struct iscsi_np *iscsit_add_np( + ret = iscsi_target_setup_login_socket(np, sockaddr); + if (ret != 0) { + kfree(np); ++ mutex_unlock(&np_lock); + return ERR_PTR(ret); + } + +@@ -369,6 +376,7 @@ struct iscsi_np *iscsit_add_np( + pr_err("Unable to create kthread: iscsi_np\n"); + ret = PTR_ERR(np->np_thread); + kfree(np); ++ mutex_unlock(&np_lock); + return ERR_PTR(ret); + } + /* +@@ -379,10 +387,10 @@ struct iscsi_np *iscsit_add_np( + * point because iscsi_np has not been added to g_np_list yet. + */ + np->np_exports = 1; ++ np->np_thread_state = ISCSI_NP_THREAD_ACTIVE; + +- spin_lock_bh(&np_lock); + list_add_tail(&np->np_list, &g_np_list); +- spin_unlock_bh(&np_lock); ++ mutex_unlock(&np_lock); + + pr_debug("CORE[0] - Added Network Portal: %s:%hu on %s\n", + np->np_ip, np->np_port, (np->np_network_transport == ISCSI_TCP) ? +@@ -453,9 +461,9 @@ int iscsit_del_np(struct iscsi_np *np) + } + iscsit_del_np_comm(np); + +- spin_lock_bh(&np_lock); ++ mutex_lock(&np_lock); + list_del(&np->np_list); +- spin_unlock_bh(&np_lock); ++ mutex_unlock(&np_lock); + + pr_debug("CORE[0] - Removed Network Portal: %s:%hu on %s\n", + np->np_ip, np->np_port, (np->np_network_transport == ISCSI_TCP) ? +diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c +index 40747feed34c..fdc669cbf7c5 100644 +--- a/drivers/tty/serial/8250/8250_pci.c ++++ b/drivers/tty/serial/8250/8250_pci.c +@@ -1142,6 +1142,7 @@ pci_xr17c154_setup(struct serial_private *priv, + #define PCI_DEVICE_ID_TITAN_800E 0xA014 + #define PCI_DEVICE_ID_TITAN_200EI 0xA016 + #define PCI_DEVICE_ID_TITAN_200EISI 0xA017 ++#define PCI_DEVICE_ID_TITAN_200V3 0xA306 + #define PCI_DEVICE_ID_TITAN_400V3 0xA310 + #define PCI_DEVICE_ID_TITAN_410V3 0xA312 + #define PCI_DEVICE_ID_TITAN_800V3 0xA314 +@@ -3456,6 +3457,9 @@ static struct pci_device_id serial_pci_tbl[] = { + { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EISI, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_oxsemi_2_4000000 }, ++ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200V3, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, ++ pbn_b0_bt_2_921600 }, + { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400V3, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b0_4_921600 }, +diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c +index ed7cd378b838..ff58d288c9c8 100644 +--- a/drivers/tty/serial/atmel_serial.c ++++ b/drivers/tty/serial/atmel_serial.c +@@ -1022,12 +1022,24 @@ static int atmel_startup(struct uart_port *port) + static void atmel_shutdown(struct uart_port *port) + { + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); ++ + /* +- * Ensure everything is stopped. ++ * Clear out any scheduled tasklets before ++ * we destroy the buffers ++ */ ++ tasklet_kill(&atmel_port->tasklet); ++ ++ /* ++ * Ensure everything is stopped and ++ * disable all interrupts, port and break condition. + */ + atmel_stop_rx(port); + atmel_stop_tx(port); + ++ UART_PUT_CR(port, ATMEL_US_RSTSTA); ++ UART_PUT_IDR(port, -1); ++ ++ + /* + * Shut-down the DMA. + */ +@@ -1054,12 +1066,6 @@ static void atmel_shutdown(struct uart_port *port) + } + + /* +- * Disable all interrupts, port and break condition. +- */ +- UART_PUT_CR(port, ATMEL_US_RSTSTA); +- UART_PUT_IDR(port, -1); +- +- /* + * Free the interrupt + */ + free_irq(port->irq, port); +diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c +index 78609d302625..6ed7e7c787d8 100644 +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -651,10 +651,6 @@ void usb_destroy_configuration(struct usb_device *dev) + * + * hub-only!! ... and only in reset path, or usb_new_device() + * (used by real hubs and virtual root hubs) +- * +- * NOTE: if this is a WUSB device and is not authorized, we skip the +- * whole thing. A non-authorized USB device has no +- * configurations. + */ + int usb_get_configuration(struct usb_device *dev) + { +@@ -666,8 +662,6 @@ int usb_get_configuration(struct usb_device *dev) + struct usb_config_descriptor *desc; + + cfgno = 0; +- if (dev->authorized == 0) /* Not really an error */ +- goto out_not_authorized; + result = -ENOMEM; + if (ncfg > USB_MAXCONFIG) { + dev_warn(ddev, "too many configurations: %d, " +@@ -749,7 +743,6 @@ int usb_get_configuration(struct usb_device *dev) + + err: + kfree(desc); +-out_not_authorized: + dev->descriptor.bNumConfigurations = cfgno; + err2: + if (result == -ENOMEM) +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 14476faf9a00..609f5a7db3f3 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -1919,18 +1919,13 @@ static int usb_enumerate_device(struct usb_device *udev) + goto fail; + } + } +- if (udev->wusb == 1 && udev->authorized == 0) { +- udev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL); +- udev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL); +- udev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL); +- } +- else { +- /* read the standard strings and cache them if present */ +- udev->product = usb_cache_string(udev, udev->descriptor.iProduct); +- udev->manufacturer = usb_cache_string(udev, +- udev->descriptor.iManufacturer); +- udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber); +- } ++ ++ /* read the standard strings and cache them if present */ ++ udev->product = usb_cache_string(udev, udev->descriptor.iProduct); ++ udev->manufacturer = usb_cache_string(udev, ++ udev->descriptor.iManufacturer); ++ udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber); ++ + err = usb_enumerate_device_otg(udev); + fail: + return err; +@@ -2084,16 +2079,6 @@ int usb_deauthorize_device(struct usb_device *usb_dev) + usb_dev->authorized = 0; + usb_set_configuration(usb_dev, -1); + +- kfree(usb_dev->product); +- usb_dev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL); +- kfree(usb_dev->manufacturer); +- usb_dev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL); +- kfree(usb_dev->serial); +- usb_dev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL); +- +- usb_destroy_configuration(usb_dev); +- usb_dev->descriptor.bNumConfigurations = 0; +- + out_unauthorized: + usb_unlock_device(usb_dev); + return 0; +@@ -2121,17 +2106,7 @@ int usb_authorize_device(struct usb_device *usb_dev) + goto error_device_descriptor; + } + +- kfree(usb_dev->product); +- usb_dev->product = NULL; +- kfree(usb_dev->manufacturer); +- usb_dev->manufacturer = NULL; +- kfree(usb_dev->serial); +- usb_dev->serial = NULL; +- + usb_dev->authorized = 1; +- result = usb_enumerate_device(usb_dev); +- if (result < 0) +- goto error_enumerate; + /* Choose and set the configuration. This registers the interfaces + * with the driver core and lets interface drivers bind to them. + */ +@@ -2147,7 +2122,6 @@ int usb_authorize_device(struct usb_device *usb_dev) + } + dev_info(&usb_dev->dev, "authorized to connect\n"); + +-error_enumerate: + error_device_descriptor: + usb_autosuspend_device(usb_dev); + error_autoresume: +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index c8ea954ede9f..b98066887127 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -315,6 +315,9 @@ static void xhci_cleanup_msix(struct xhci_hcd *xhci) + struct usb_hcd *hcd = xhci_to_hcd(xhci); + struct pci_dev *pdev = to_pci_dev(hcd->self.controller); + ++ if (xhci->quirks & XHCI_PLAT) ++ return; ++ + xhci_free_irq(xhci); + + if (xhci->msix_entries) { +diff --git a/drivers/usb/serial/cypress_m8.h b/drivers/usb/serial/cypress_m8.h +index b461311a2ae7..ce13e61b7d55 100644 +--- a/drivers/usb/serial/cypress_m8.h ++++ b/drivers/usb/serial/cypress_m8.h +@@ -63,7 +63,7 @@ + #define UART_DSR 0x20 /* data set ready - flow control - device to host */ + #define CONTROL_RTS 0x10 /* request to send - flow control - host to device */ + #define UART_CTS 0x10 /* clear to send - flow control - device to host */ +-#define UART_RI 0x10 /* ring indicator - modem - device to host */ ++#define UART_RI 0x80 /* ring indicator - modem - device to host */ + #define UART_CD 0x40 /* carrier detect - modem - device to host */ + #define CYP_ERROR 0x08 /* received from input report - device to host */ + /* Note - the below has nothing to do with the "feature report" reset */ +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 66f5e5472c17..9d7e865a518f 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -325,6 +325,9 @@ static void option_instat_callback(struct urb *urb); + * It seems to contain a Qualcomm QSC6240/6290 chipset */ + #define FOUR_G_SYSTEMS_PRODUCT_W14 0x9603 + ++/* iBall 3.5G connect wireless modem */ ++#define IBALL_3_5G_CONNECT 0x9605 ++ + /* Zoom */ + #define ZOOM_PRODUCT_4597 0x9607 + +@@ -1461,6 +1464,17 @@ static const struct usb_device_id option_ids[] = { + .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffe9, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8b, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8c, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8d, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8e, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8f, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff90, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff91, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff92, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff93, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff94, 0xff, 0xff, 0xff) }, + + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, +@@ -1509,6 +1523,7 @@ static const struct usb_device_id option_ids[] = { + .driver_info = (kernel_ulong_t)&four_g_w14_blacklist + }, + { 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) }, + /* Pirelli */ + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_1)}, +diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h +index cf442e012da3..08d69e5fc143 100644 +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -226,6 +226,13 @@ UNUSUAL_DEV( 0x0421, 0x0495, 0x0370, 0x0370, + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_MAX_SECTORS_64 ), + ++/* Patch submitted by Mikhail Zolotaryov */ ++UNUSUAL_DEV( 0x0421, 0x06aa, 0x1110, 0x1110, ++ "Nokia", ++ "502", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_MAX_SECTORS_64 ), ++ + #ifdef NO_SDDR09 + UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100, + "Microtech", +diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c +index c4f0a9936f88..224ce21cc0ac 100644 +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -7033,7 +7033,7 @@ out: + */ + if (root_dropped == false) + btrfs_add_dead_root(root); +- if (err) ++ if (err && err != -EAGAIN) + btrfs_std_error(root->fs_info, err); + return err; + } +diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h +index 6baa73dcfce1..4f42a9cb5604 100644 +--- a/include/linux/hugetlb.h ++++ b/include/linux/hugetlb.h +@@ -24,6 +24,7 @@ struct hugepage_subpool *hugepage_new_subpool(long nr_blocks); + void hugepage_put_subpool(struct hugepage_subpool *spool); + + int PageHuge(struct page *page); ++int PageHeadHuge(struct page *page_head); + + void reset_vma_resv_huge_pages(struct vm_area_struct *vma); + int hugetlb_sysctl_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); +@@ -85,6 +86,11 @@ static inline int PageHuge(struct page *page) + return 0; + } + ++static inline int PageHeadHuge(struct page *page_head) ++{ ++ return 0; ++} ++ + static inline void reset_vma_resv_huge_pages(struct vm_area_struct *vma) + { + } +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index af20b77a624a..7111f2f5af68 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -679,6 +679,23 @@ int PageHuge(struct page *page) + } + EXPORT_SYMBOL_GPL(PageHuge); + ++/* ++ * PageHeadHuge() only returns true for hugetlbfs head page, but not for ++ * normal or transparent huge pages. ++ */ ++int PageHeadHuge(struct page *page_head) ++{ ++ compound_page_dtor *dtor; ++ ++ if (!PageHead(page_head)) ++ return 0; ++ ++ dtor = get_compound_page_dtor(page_head); ++ ++ return dtor == free_huge_page; ++} ++EXPORT_SYMBOL_GPL(PageHeadHuge); ++ + pgoff_t __basepage_index(struct page *page) + { + struct page *page_head = compound_head(page); +diff --git a/mm/swap.c b/mm/swap.c +index f689e9a03204..a8feea68a606 100644 +--- a/mm/swap.c ++++ b/mm/swap.c +@@ -77,18 +77,6 @@ static void __put_compound_page(struct page *page) + + static void put_compound_page(struct page *page) + { +- /* +- * hugetlbfs pages cannot be split from under us. If this is a +- * hugetlbfs page, check refcount on head page and release the page if +- * the refcount becomes zero. +- */ +- if (PageHuge(page)) { +- page = compound_head(page); +- if (put_page_testzero(page)) +- __put_compound_page(page); +- return; +- } +- + if (unlikely(PageTail(page))) { + /* __split_huge_page_refcount can run under us */ + struct page *page_head = compound_trans_head(page); +@@ -96,6 +84,35 @@ static void put_compound_page(struct page *page) + if (likely(page != page_head && + get_page_unless_zero(page_head))) { + unsigned long flags; ++ ++ if (PageHeadHuge(page_head)) { ++ if (likely(PageTail(page))) { ++ /* ++ * __split_huge_page_refcount ++ * cannot race here. ++ */ ++ VM_BUG_ON(!PageHead(page_head)); ++ atomic_dec(&page->_mapcount); ++ if (put_page_testzero(page_head)) ++ VM_BUG_ON(1); ++ if (put_page_testzero(page_head)) ++ __put_compound_page(page_head); ++ return; ++ } else { ++ /* ++ * __split_huge_page_refcount ++ * run before us, "page" was a ++ * THP tail. The split ++ * page_head has been freed ++ * and reallocated as slab or ++ * hugetlbfs page of smaller ++ * order (only possible if ++ * reallocated as slab on ++ * x86). ++ */ ++ goto skip_lock; ++ } ++ } + /* + * page_head wasn't a dangling pointer but it + * may not be a head page anymore by the time +@@ -107,9 +124,29 @@ static void put_compound_page(struct page *page) + /* __split_huge_page_refcount run before us */ + compound_unlock_irqrestore(page_head, flags); + VM_BUG_ON(PageHead(page_head)); +- if (put_page_testzero(page_head)) +- __put_single_page(page_head); +- out_put_single: ++skip_lock: ++ if (put_page_testzero(page_head)) { ++ /* ++ * The head page may have been ++ * freed and reallocated as a ++ * compound page of smaller ++ * order and then freed again. ++ * All we know is that it ++ * cannot have become: a THP ++ * page, a compound page of ++ * higher order, a tail page. ++ * That is because we still ++ * hold the refcount of the ++ * split THP tail and ++ * page_head was the THP head ++ * before the split. ++ */ ++ if (PageHead(page_head)) ++ __put_compound_page(page_head); ++ else ++ __put_single_page(page_head); ++ } ++out_put_single: + if (put_page_testzero(page)) + __put_single_page(page); + return; +@@ -173,21 +210,34 @@ bool __get_page_tail(struct page *page) + */ + unsigned long flags; + bool got = false; +- struct page *page_head; ++ struct page *page_head = compound_trans_head(page); + +- /* +- * If this is a hugetlbfs page it cannot be split under us. Simply +- * increment refcount for the head page. +- */ +- if (PageHuge(page)) { +- page_head = compound_head(page); +- atomic_inc(&page_head->_count); +- got = true; +- goto out; +- } +- +- page_head = compound_trans_head(page); + if (likely(page != page_head && get_page_unless_zero(page_head))) { ++ /* Ref to put_compound_page() comment. */ ++ if (PageHeadHuge(page_head)) { ++ if (likely(PageTail(page))) { ++ /* ++ * This is a hugetlbfs ++ * page. __split_huge_page_refcount ++ * cannot race here. ++ */ ++ VM_BUG_ON(!PageHead(page_head)); ++ __get_page_tail_foll(page, false); ++ return true; ++ } else { ++ /* ++ * __split_huge_page_refcount run ++ * before us, "page" was a THP ++ * tail. The split page_head has been ++ * freed and reallocated as slab or ++ * hugetlbfs page of smaller order ++ * (only possible if reallocated as ++ * slab on x86). ++ */ ++ put_page(page_head); ++ return false; ++ } ++ } + /* + * page_head wasn't a dangling pointer but it + * may not be a head page anymore by the time +@@ -204,7 +254,6 @@ bool __get_page_tail(struct page *page) + if (unlikely(!got)) + put_page(page_head); + } +-out: + return got; + } + EXPORT_SYMBOL(__get_page_tail); +diff --git a/net/compat.c b/net/compat.c +index 17f997e14f63..93f542335e19 100644 +--- a/net/compat.c ++++ b/net/compat.c +@@ -789,21 +789,16 @@ asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg, + if (flags & MSG_CMSG_COMPAT) + return -EINVAL; + +- if (COMPAT_USE_64BIT_TIME) +- return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, +- flags | MSG_CMSG_COMPAT, +- (struct timespec *) timeout); +- + if (timeout == NULL) + return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, + flags | MSG_CMSG_COMPAT, NULL); + +- if (get_compat_timespec(&ktspec, timeout)) ++ if (compat_get_timespec(&ktspec, timeout)) + return -EFAULT; + + datagrams = __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, + flags | MSG_CMSG_COMPAT, &ktspec); +- if (datagrams > 0 && put_compat_timespec(&ktspec, timeout)) ++ if (datagrams > 0 && compat_put_timespec(&ktspec, timeout)) + datagrams = -EFAULT; + + return datagrams; +diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c +index 5fcc8df3f179..8cb3091c8f63 100644 +--- a/net/ipv4/inet_diag.c ++++ b/net/ipv4/inet_diag.c +@@ -941,7 +941,7 @@ next_normal: + ++num; + } + +- if (r->idiag_states & TCPF_TIME_WAIT) { ++ if (r->idiag_states & (TCPF_TIME_WAIT | TCPF_FIN_WAIT2)) { + struct inet_timewait_sock *tw; + + inet_twsk_for_each(tw, node, +@@ -949,6 +949,8 @@ next_normal: + + if (num < s_num) + goto next_dying; ++ if (!(r->idiag_states & (1 << tw->tw_substate))) ++ goto next_dying; + if (r->sdiag_family != AF_UNSPEC && + tw->tw_family != r->sdiag_family) + goto next_dying; +diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c +index a0b7166badb0..94cd1ef1e319 100644 +--- a/net/ipv4/ipmr.c ++++ b/net/ipv4/ipmr.c +@@ -154,9 +154,12 @@ static struct mr_table *ipmr_get_table(struct net *net, u32 id) + static int ipmr_fib_lookup(struct net *net, struct flowi4 *flp4, + struct mr_table **mrt) + { +- struct ipmr_result res; +- struct fib_lookup_arg arg = { .result = &res, }; + int err; ++ struct ipmr_result res; ++ struct fib_lookup_arg arg = { ++ .result = &res, ++ .flags = FIB_LOOKUP_NOREF, ++ }; + + err = fib_rules_lookup(net->ipv4.mr_rules_ops, + flowi4_to_flowi(flp4), 0, &arg); +diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c +index d5e4615e52c4..abe1f768b5b6 100644 +--- a/net/ipv6/ip6mr.c ++++ b/net/ipv6/ip6mr.c +@@ -138,9 +138,12 @@ static struct mr6_table *ip6mr_get_table(struct net *net, u32 id) + static int ip6mr_fib_lookup(struct net *net, struct flowi6 *flp6, + struct mr6_table **mrt) + { +- struct ip6mr_result res; +- struct fib_lookup_arg arg = { .result = &res, }; + int err; ++ struct ip6mr_result res; ++ struct fib_lookup_arg arg = { ++ .result = &res, ++ .flags = FIB_LOOKUP_NOREF, ++ }; + + err = fib_rules_lookup(net->ipv6.mr6_rules_ops, + flowi6_to_flowi(flp6), 0, &arg); +diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig +index 5ca0939e4223..cb53e8d97ff1 100644 +--- a/sound/pci/Kconfig ++++ b/sound/pci/Kconfig +@@ -30,6 +30,7 @@ config SND_ALS300 + select SND_PCM + select SND_AC97_CODEC + select SND_OPL3_LIB ++ select ZONE_DMA + help + Say 'Y' or 'M' to include support for Avance Logic ALS300/ALS300+ + +@@ -54,6 +55,7 @@ config SND_ALI5451 + tristate "ALi M5451 PCI Audio Controller" + select SND_MPU401_UART + select SND_AC97_CODEC ++ select ZONE_DMA + help + Say Y here to include support for the integrated AC97 sound + device on motherboards using the ALi M5451 Audio Controller +@@ -158,6 +160,7 @@ config SND_AZT3328 + select SND_PCM + select SND_RAWMIDI + select SND_AC97_CODEC ++ select ZONE_DMA + help + Say Y here to include support for Aztech AZF3328 (PCI168) + soundcards. +@@ -463,6 +466,7 @@ config SND_EMU10K1 + select SND_HWDEP + select SND_RAWMIDI + select SND_AC97_CODEC ++ select ZONE_DMA + help + Say Y to include support for Sound Blaster PCI 512, Live!, + Audigy and E-mu APS (partially supported) soundcards. +@@ -478,6 +482,7 @@ config SND_EMU10K1X + tristate "Emu10k1X (Dell OEM Version)" + select SND_AC97_CODEC + select SND_RAWMIDI ++ select ZONE_DMA + help + Say Y here to include support for the Dell OEM version of the + Sound Blaster Live!. +@@ -511,6 +516,7 @@ config SND_ES1938 + select SND_OPL3_LIB + select SND_MPU401_UART + select SND_AC97_CODEC ++ select ZONE_DMA + help + Say Y here to include support for soundcards based on ESS Solo-1 + (ES1938, ES1946, ES1969) chips. +@@ -522,6 +528,7 @@ config SND_ES1968 + tristate "ESS ES1968/1978 (Maestro-1/2/2E)" + select SND_MPU401_UART + select SND_AC97_CODEC ++ select ZONE_DMA + help + Say Y here to include support for soundcards based on ESS Maestro + 1/2/2E chips. +@@ -602,6 +609,7 @@ config SND_ICE1712 + select SND_MPU401_UART + select SND_AC97_CODEC + select BITREVERSE ++ select ZONE_DMA + help + Say Y here to include support for soundcards based on the + ICE1712 (Envy24) chip. +@@ -688,6 +696,7 @@ config SND_LX6464ES + config SND_MAESTRO3 + tristate "ESS Allegro/Maestro3" + select SND_AC97_CODEC ++ select ZONE_DMA + help + Say Y here to include support for soundcards based on ESS Maestro 3 + (Allegro) chips. +@@ -782,6 +791,7 @@ config SND_SIS7019 + tristate "SiS 7019 Audio Accelerator" + depends on X86 && !X86_64 + select SND_AC97_CODEC ++ select ZONE_DMA + help + Say Y here to include support for the SiS 7019 Audio Accelerator. + +@@ -793,6 +803,7 @@ config SND_SONICVIBES + select SND_OPL3_LIB + select SND_MPU401_UART + select SND_AC97_CODEC ++ select ZONE_DMA + help + Say Y here to include support for soundcards based on the S3 + SonicVibes chip. +@@ -804,6 +815,7 @@ config SND_TRIDENT + tristate "Trident 4D-Wave DX/NX; SiS 7018" + select SND_MPU401_UART + select SND_AC97_CODEC ++ select ZONE_DMA + help + Say Y here to include support for soundcards based on Trident + 4D-Wave DX/NX or SiS 7018 chips. +diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c +index b737d1619cc7..f466080b8724 100644 +--- a/sound/pci/rme9652/rme9652.c ++++ b/sound/pci/rme9652/rme9652.c +@@ -285,7 +285,7 @@ static char channel_map_9636_ds[26] = { + /* ADAT channels are remapped */ + 1, 3, 5, 7, 9, 11, 13, 15, + /* channels 8 and 9 are S/PDIF */ +- 24, 25 ++ 24, 25, + /* others don't exist */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; +diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c +index 78e9ce48bb99..192fc75f1f20 100644 +--- a/sound/soc/codecs/adau1701.c ++++ b/sound/soc/codecs/adau1701.c +@@ -64,7 +64,7 @@ + + #define ADAU1701_SEROCTL_WORD_LEN_24 0x0000 + #define ADAU1701_SEROCTL_WORD_LEN_20 0x0001 +-#define ADAU1701_SEROCTL_WORD_LEN_16 0x0010 ++#define ADAU1701_SEROCTL_WORD_LEN_16 0x0002 + #define ADAU1701_SEROCTL_WORD_LEN_MASK 0x0003 + + #define ADAU1701_AUXNPOW_VBPD 0x40 diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.79-80.patch b/patch/kernel/sun8i-default/0001-patch-3.4.79-80.patch new file mode 100644 index 000000000..e9a78876b --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.79-80.patch @@ -0,0 +1,939 @@ +diff --git a/Makefile b/Makefile +index 7e9c23f19fe4..7b6c9ec4922b 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 79 ++SUBLEVEL = 80 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c +index cf02e971467f..0bf5ec2d5818 100644 +--- a/drivers/acpi/bus.c ++++ b/drivers/acpi/bus.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + #ifdef CONFIG_X86 + #include + #endif +@@ -921,6 +922,14 @@ void __init acpi_early_init(void) + goto error0; + } + ++ /* ++ * If the system is using ACPI then we can be reasonably ++ * confident that any regulators are managed by the firmware ++ * so tell the regulator core it has everything it needs to ++ * know. ++ */ ++ regulator_has_full_constraints(); ++ + return; + + error0: +diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c +index 2cbd369e0fcb..7b4cfc54ddb4 100644 +--- a/drivers/gpu/drm/radeon/evergreen_cs.c ++++ b/drivers/gpu/drm/radeon/evergreen_cs.c +@@ -942,7 +942,10 @@ static int evergreen_cs_track_check(struct radeon_cs_parser *p) + if (track->cb_dirty) { + tmp = track->cb_target_mask; + for (i = 0; i < 8; i++) { +- if ((tmp >> (i * 4)) & 0xF) { ++ u32 format = G_028C70_FORMAT(track->cb_color_info[i]); ++ ++ if (format != V_028C70_COLOR_INVALID && ++ (tmp >> (i * 4)) & 0xF) { + /* at least one component is enabled */ + if (track->cb_color_bo[i] == NULL) { + dev_warn(p->dev, "%s:%d mask 0x%08X | 0x%08X no cb for %d\n", +diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c +index 8c403d946acc..49b622904217 100644 +--- a/drivers/gpu/drm/radeon/r600.c ++++ b/drivers/gpu/drm/radeon/r600.c +@@ -2313,14 +2313,17 @@ void r600_fence_ring_emit(struct radeon_device *rdev, + struct radeon_fence *fence) + { + struct radeon_ring *ring = &rdev->ring[fence->ring]; ++ u32 cp_coher_cntl = PACKET3_TC_ACTION_ENA | PACKET3_VC_ACTION_ENA | ++ PACKET3_SH_ACTION_ENA; ++ ++ if (rdev->family >= CHIP_RV770) ++ cp_coher_cntl |= PACKET3_FULL_CACHE_ENA; + + if (rdev->wb.use_event) { + u64 addr = rdev->fence_drv[fence->ring].gpu_addr; + /* flush read cache over gart */ + radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); +- radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | +- PACKET3_VC_ACTION_ENA | +- PACKET3_SH_ACTION_ENA); ++ radeon_ring_write(ring, cp_coher_cntl); + radeon_ring_write(ring, 0xFFFFFFFF); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 10); /* poll interval */ +@@ -2334,9 +2337,7 @@ void r600_fence_ring_emit(struct radeon_device *rdev, + } else { + /* flush read cache over gart */ + radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); +- radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | +- PACKET3_VC_ACTION_ENA | +- PACKET3_SH_ACTION_ENA); ++ radeon_ring_write(ring, cp_coher_cntl); + radeon_ring_write(ring, 0xFFFFFFFF); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 10); /* poll interval */ +diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c +index b8e12af304a9..3cd9b0e6f5b3 100644 +--- a/drivers/gpu/drm/radeon/r600_cs.c ++++ b/drivers/gpu/drm/radeon/r600_cs.c +@@ -747,7 +747,10 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) + if (track->cb_dirty) { + tmp = track->cb_target_mask; + for (i = 0; i < 8; i++) { +- if ((tmp >> (i * 4)) & 0xF) { ++ u32 format = G_0280A0_FORMAT(track->cb_color_info[i]); ++ ++ if (format != V_0280A0_COLOR_INVALID && ++ (tmp >> (i * 4)) & 0xF) { + /* at least one component is enabled */ + if (track->cb_color_bo[i] == NULL) { + dev_warn(p->dev, "%s:%d mask 0x%08X | 0x%08X no cb for %d\n", +diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h +index 12ceb829a03e..02bb23821ce2 100644 +--- a/drivers/gpu/drm/radeon/r600d.h ++++ b/drivers/gpu/drm/radeon/r600d.h +@@ -873,6 +873,7 @@ + #define PACKET3_INDIRECT_BUFFER 0x32 + #define PACKET3_SURFACE_SYNC 0x43 + # define PACKET3_CB0_DEST_BASE_ENA (1 << 6) ++# define PACKET3_FULL_CACHE_ENA (1 << 20) /* r7xx+ only */ + # define PACKET3_TC_ACTION_ENA (1 << 23) + # define PACKET3_VC_ACTION_ENA (1 << 24) + # define PACKET3_CB_ACTION_ENA (1 << 25) +diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c +index c54d295c6be3..6d0c32b9e8aa 100644 +--- a/drivers/gpu/drm/radeon/radeon_atombios.c ++++ b/drivers/gpu/drm/radeon/radeon_atombios.c +@@ -2785,6 +2785,10 @@ void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) + /* tell the bios not to handle mode switching */ + bios_6_scratch |= ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH; + ++ /* clear the vbios dpms state */ ++ if (ASIC_IS_DCE4(rdev)) ++ bios_2_scratch &= ~ATOM_S2_DEVICE_DPMS_STATE; ++ + if (rdev->family >= CHIP_R600) { + WREG32(R600_BIOS_2_SCRATCH, bios_2_scratch); + WREG32(R600_BIOS_6_SCRATCH, bios_6_scratch); +diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c +index 6076e85aa5da..19d68c55c7e6 100644 +--- a/drivers/gpu/drm/radeon/radeon_i2c.c ++++ b/drivers/gpu/drm/radeon/radeon_i2c.c +@@ -1020,6 +1020,9 @@ void radeon_i2c_destroy(struct radeon_i2c_chan *i2c) + /* Add the default buses */ + void radeon_i2c_init(struct radeon_device *rdev) + { ++ if (radeon_hw_i2c) ++ DRM_INFO("hw_i2c forced on, you may experience display detection problems!\n"); ++ + if (rdev->is_atom_bios) + radeon_atombios_i2c_init(rdev); + else +diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c +index bf6ca2d8a28b..4c5a7934b3e3 100644 +--- a/drivers/gpu/drm/radeon/radeon_pm.c ++++ b/drivers/gpu/drm/radeon/radeon_pm.c +@@ -587,8 +587,10 @@ void radeon_pm_resume(struct radeon_device *rdev) + rdev->pm.current_clock_mode_index = 0; + rdev->pm.current_sclk = rdev->pm.default_sclk; + rdev->pm.current_mclk = rdev->pm.default_mclk; +- rdev->pm.current_vddc = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage; +- rdev->pm.current_vddci = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.vddci; ++ if (rdev->pm.power_state) { ++ rdev->pm.current_vddc = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage; ++ rdev->pm.current_vddci = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.vddci; ++ } + if (rdev->pm.pm_method == PM_METHOD_DYNPM + && rdev->pm.dynpm_state == DYNPM_STATE_SUSPENDED) { + rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; +diff --git a/drivers/infiniband/hw/qib/qib_ud.c b/drivers/infiniband/hw/qib/qib_ud.c +index 828609fa4d28..c0d93d474ccb 100644 +--- a/drivers/infiniband/hw/qib/qib_ud.c ++++ b/drivers/infiniband/hw/qib/qib_ud.c +@@ -57,13 +57,20 @@ static void qib_ud_loopback(struct qib_qp *sqp, struct qib_swqe *swqe) + struct qib_sge *sge; + struct ib_wc wc; + u32 length; ++ enum ib_qp_type sqptype, dqptype; + + qp = qib_lookup_qpn(ibp, swqe->wr.wr.ud.remote_qpn); + if (!qp) { + ibp->n_pkt_drops++; + return; + } +- if (qp->ibqp.qp_type != sqp->ibqp.qp_type || ++ ++ sqptype = sqp->ibqp.qp_type == IB_QPT_GSI ? ++ IB_QPT_UD : sqp->ibqp.qp_type; ++ dqptype = qp->ibqp.qp_type == IB_QPT_GSI ? ++ IB_QPT_UD : qp->ibqp.qp_type; ++ ++ if (dqptype != sqptype || + !(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK)) { + ibp->n_pkt_drops++; + goto drop; +diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c +index abc6ac855598..4e1c6bfc9c8d 100644 +--- a/drivers/iommu/intel-iommu.c ++++ b/drivers/iommu/intel-iommu.c +@@ -913,7 +913,7 @@ static void dma_pte_free_level(struct dmar_domain *domain, int level, + + /* If range covers entire pagetable, free it */ + if (!(start_pfn > level_pfn || +- last_pfn < level_pfn + level_size(level))) { ++ last_pfn < level_pfn + level_size(level) - 1)) { + dma_clear_pte(pte); + domain_flush_cache(domain, pte, sizeof(*pte)); + free_pgtable_page(level_pte); +diff --git a/drivers/md/dm-sysfs.c b/drivers/md/dm-sysfs.c +index 84d2b91e4efb..e0cc5d6a9e46 100644 +--- a/drivers/md/dm-sysfs.c ++++ b/drivers/md/dm-sysfs.c +@@ -79,6 +79,11 @@ static const struct sysfs_ops dm_sysfs_ops = { + .show = dm_attr_show, + }; + ++static void dm_kobject_release(struct kobject *kobj) ++{ ++ complete(dm_get_completion_from_kobject(kobj)); ++} ++ + /* + * dm kobject is embedded in mapped_device structure + * no need to define release function here +@@ -86,6 +91,7 @@ static const struct sysfs_ops dm_sysfs_ops = { + static struct kobj_type dm_ktype = { + .sysfs_ops = &dm_sysfs_ops, + .default_attrs = dm_attrs, ++ .release = dm_kobject_release, + }; + + /* +@@ -104,5 +110,7 @@ int dm_sysfs_init(struct mapped_device *md) + */ + void dm_sysfs_exit(struct mapped_device *md) + { +- kobject_put(dm_kobject(md)); ++ struct kobject *kobj = dm_kobject(md); ++ kobject_put(kobj); ++ wait_for_completion(dm_get_completion_from_kobject(kobj)); + } +diff --git a/drivers/md/dm.c b/drivers/md/dm.c +index 32370ea32e22..d26fddf7c1fb 100644 +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -194,6 +194,9 @@ struct mapped_device { + /* sysfs handle */ + struct kobject kobj; + ++ /* wait until the kobject is released */ ++ struct completion kobj_completion; ++ + /* zero-length flush that will be cloned and submitted to targets */ + struct bio flush_bio; + }; +@@ -1891,6 +1894,7 @@ static struct mapped_device *alloc_dev(int minor) + init_waitqueue_head(&md->wait); + INIT_WORK(&md->work, dm_wq_work); + init_waitqueue_head(&md->eventq); ++ init_completion(&md->kobj_completion); + + md->disk->major = _major; + md->disk->first_minor = minor; +@@ -2705,6 +2709,13 @@ struct mapped_device *dm_get_from_kobject(struct kobject *kobj) + return md; + } + ++struct completion *dm_get_completion_from_kobject(struct kobject *kobj) ++{ ++ struct mapped_device *md = container_of(kobj, struct mapped_device, kobj); ++ ++ return &md->kobj_completion; ++} ++ + int dm_suspended_md(struct mapped_device *md) + { + return test_bit(DMF_SUSPENDED, &md->flags); +diff --git a/drivers/md/dm.h b/drivers/md/dm.h +index b7dacd59d8d7..1174e9654882 100644 +--- a/drivers/md/dm.h ++++ b/drivers/md/dm.h +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + + /* + * Suspend feature flags +@@ -123,6 +124,7 @@ int dm_sysfs_init(struct mapped_device *md); + void dm_sysfs_exit(struct mapped_device *md); + struct kobject *dm_kobject(struct mapped_device *md); + struct mapped_device *dm_get_from_kobject(struct kobject *kobj); ++struct completion *dm_get_completion_from_kobject(struct kobject *kobj); + + /* + * Targets for linear and striped mappings +diff --git a/drivers/md/persistent-data/dm-space-map-common.c b/drivers/md/persistent-data/dm-space-map-common.c +index ff3beed6ad2d..79c02d90ce39 100644 +--- a/drivers/md/persistent-data/dm-space-map-common.c ++++ b/drivers/md/persistent-data/dm-space-map-common.c +@@ -244,6 +244,10 @@ int sm_ll_extend(struct ll_disk *ll, dm_block_t extra_blocks) + return -EINVAL; + } + ++ /* ++ * We need to set this before the dm_tm_new_block() call below. ++ */ ++ ll->nr_blocks = nr_blocks; + for (i = old_blocks; i < blocks; i++) { + struct dm_block *b; + struct disk_index_entry idx; +@@ -251,6 +255,7 @@ int sm_ll_extend(struct ll_disk *ll, dm_block_t extra_blocks) + r = dm_tm_new_block(ll->tm, &dm_sm_bitmap_validator, &b); + if (r < 0) + return r; ++ + idx.blocknr = cpu_to_le64(dm_block_location(b)); + + r = dm_tm_unlock(ll->tm, b); +@@ -265,7 +270,6 @@ int sm_ll_extend(struct ll_disk *ll, dm_block_t extra_blocks) + return r; + } + +- ll->nr_blocks = nr_blocks; + return 0; + } + +diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c +index 2a822d9e4684..e6f08d945709 100644 +--- a/drivers/mmc/host/atmel-mci.c ++++ b/drivers/mmc/host/atmel-mci.c +@@ -1022,11 +1022,22 @@ static void atmci_start_request(struct atmel_mci *host, + iflags |= ATMCI_CMDRDY; + cmd = mrq->cmd; + cmdflags = atmci_prepare_command(slot->mmc, cmd); +- atmci_send_command(host, cmd, cmdflags); ++ ++ /* ++ * DMA transfer should be started before sending the command to avoid ++ * unexpected errors especially for read operations in SDIO mode. ++ * Unfortunately, in PDC mode, command has to be sent before starting ++ * the transfer. ++ */ ++ if (host->submit_data != &atmci_submit_data_dma) ++ atmci_send_command(host, cmd, cmdflags); + + if (data) + host->submit_data(host, data); + ++ if (host->submit_data == &atmci_submit_data_dma) ++ atmci_send_command(host, cmd, cmdflags); ++ + if (mrq->stop) { + host->stop_cmdr = atmci_prepare_command(slot->mmc, mrq->stop); + host->stop_cmdr |= ATMCI_CMDR_STOP_XFER; +diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c +index 6f87c7464eca..a06231f25f06 100644 +--- a/drivers/mtd/nand/mxc_nand.c ++++ b/drivers/mtd/nand/mxc_nand.c +@@ -596,7 +596,6 @@ static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat, + ecc_stat >>= 4; + } while (--no_subpages); + +- mtd->ecc_stats.corrected += ret; + pr_debug("%d Symbol Correctable RS-ECC Error\n", ret); + + return ret; +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index d08c0d8ec22e..a7f6dcea0d76 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -1984,10 +1984,6 @@ void pci_enable_ari(struct pci_dev *dev) + if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn) + return; + +- pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); +- if (!pos) +- return; +- + bridge = dev->bus->self; + if (!bridge || !pci_is_pcie(bridge)) + return; +@@ -2006,10 +2002,14 @@ void pci_enable_ari(struct pci_dev *dev) + return; + + pci_read_config_word(bridge, pos + PCI_EXP_DEVCTL2, &ctrl); +- ctrl |= PCI_EXP_DEVCTL2_ARI; ++ if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI)) { ++ ctrl |= PCI_EXP_DEVCTL2_ARI; ++ bridge->ari_enabled = 1; ++ } else { ++ ctrl &= ~PCI_EXP_DEVCTL2_ARI; ++ bridge->ari_enabled = 0; ++ } + pci_write_config_word(bridge, pos + PCI_EXP_DEVCTL2, ctrl); +- +- bridge->ari_enabled = 1; + } + + /** +diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c +index 5f8844c1eaad..5f2eddbbff27 100644 +--- a/drivers/rtc/rtc-cmos.c ++++ b/drivers/rtc/rtc-cmos.c +@@ -34,11 +34,11 @@ + #include + #include + #include +-#include + #include + #include + #include + #include ++#include + + /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ + #include +@@ -377,6 +377,51 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) + return 0; + } + ++/* ++ * Do not disable RTC alarm on shutdown - workaround for b0rked BIOSes. ++ */ ++static bool alarm_disable_quirk; ++ ++static int __init set_alarm_disable_quirk(const struct dmi_system_id *id) ++{ ++ alarm_disable_quirk = true; ++ pr_info("rtc-cmos: BIOS has alarm-disable quirk. "); ++ pr_info("RTC alarms disabled\n"); ++ return 0; ++} ++ ++static const struct dmi_system_id rtc_quirks[] __initconst = { ++ /* https://bugzilla.novell.com/show_bug.cgi?id=805740 */ ++ { ++ .callback = set_alarm_disable_quirk, ++ .ident = "IBM Truman", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "4852570"), ++ }, ++ }, ++ /* https://bugzilla.novell.com/show_bug.cgi?id=812592 */ ++ { ++ .callback = set_alarm_disable_quirk, ++ .ident = "Gigabyte GA-990XA-UD3", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, ++ "Gigabyte Technology Co., Ltd."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "GA-990XA-UD3"), ++ }, ++ }, ++ /* http://permalink.gmane.org/gmane.linux.kernel/1604474 */ ++ { ++ .callback = set_alarm_disable_quirk, ++ .ident = "Toshiba Satellite L300", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L300"), ++ }, ++ }, ++ {} ++}; ++ + static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled) + { + struct cmos_rtc *cmos = dev_get_drvdata(dev); +@@ -385,6 +430,9 @@ static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled) + if (!is_valid_irq(cmos->irq)) + return -EINVAL; + ++ if (alarm_disable_quirk) ++ return 0; ++ + spin_lock_irqsave(&rtc_lock, flags); + + if (enabled) +@@ -1166,6 +1214,8 @@ static int __init cmos_init(void) + platform_driver_registered = true; + } + ++ dmi_check_system(rtc_quirks); ++ + if (retval == 0) + return 0; + +diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c +index 3d8f662e4fe9..b7a034a3259e 100644 +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -572,7 +572,9 @@ static void spi_pump_messages(struct kthread_work *work) + ret = master->transfer_one_message(master, master->cur_msg); + if (ret) { + dev_err(&master->dev, +- "failed to transfer one message from queue\n"); ++ "failed to transfer one message from queue: %d\n", ret); ++ master->cur_msg->status = ret; ++ spi_finalize_current_message(master); + return; + } + } +diff --git a/fs/exofs/ore.c b/fs/exofs/ore.c +index 1585db1aa365..a73bc268907f 100644 +--- a/fs/exofs/ore.c ++++ b/fs/exofs/ore.c +@@ -103,7 +103,7 @@ int ore_verify_layout(unsigned total_comps, struct ore_layout *layout) + + layout->max_io_length = + (BIO_MAX_PAGES_KMALLOC * PAGE_SIZE - layout->stripe_unit) * +- layout->group_width; ++ (layout->group_width - layout->parity); + if (layout->parity) { + unsigned stripe_length = + (layout->group_width - layout->parity) * +@@ -286,7 +286,8 @@ int ore_get_rw_state(struct ore_layout *layout, struct ore_components *oc, + if (length) { + ore_calc_stripe_info(layout, offset, length, &ios->si); + ios->length = ios->si.length; +- ios->nr_pages = (ios->length + PAGE_SIZE - 1) / PAGE_SIZE; ++ ios->nr_pages = ((ios->offset & (PAGE_SIZE - 1)) + ++ ios->length + PAGE_SIZE - 1) / PAGE_SIZE; + if (layout->parity) + _ore_post_alloc_raid_stuff(ios); + } +@@ -536,6 +537,7 @@ void ore_calc_stripe_info(struct ore_layout *layout, u64 file_offset, + u64 H = LmodS - G * T; + + u32 N = div_u64(H, U); ++ u32 Nlast; + + /* "H - (N * U)" is just "H % U" so it's bound to u32 */ + u32 C = (u32)(H - (N * U)) / stripe_unit + G * group_width; +@@ -568,6 +570,10 @@ void ore_calc_stripe_info(struct ore_layout *layout, u64 file_offset, + si->length = T - H; + if (si->length > length) + si->length = length; ++ ++ Nlast = div_u64(H + si->length + U - 1, U); ++ si->maxdevUnits = Nlast - N; ++ + si->M = M; + } + EXPORT_SYMBOL(ore_calc_stripe_info); +@@ -583,13 +589,16 @@ int _ore_add_stripe_unit(struct ore_io_state *ios, unsigned *cur_pg, + int ret; + + if (per_dev->bio == NULL) { +- unsigned pages_in_stripe = ios->layout->group_width * +- (ios->layout->stripe_unit / PAGE_SIZE); +- unsigned nr_pages = ios->nr_pages * ios->layout->group_width / +- (ios->layout->group_width - +- ios->layout->parity); +- unsigned bio_size = (nr_pages + pages_in_stripe) / +- ios->layout->group_width; ++ unsigned bio_size; ++ ++ if (!ios->reading) { ++ bio_size = ios->si.maxdevUnits; ++ } else { ++ bio_size = (ios->si.maxdevUnits + 1) * ++ (ios->layout->group_width - ios->layout->parity) / ++ ios->layout->group_width; ++ } ++ bio_size *= (ios->layout->stripe_unit / PAGE_SIZE); + + per_dev->bio = bio_kmalloc(GFP_KERNEL, bio_size); + if (unlikely(!per_dev->bio)) { +@@ -609,8 +618,12 @@ int _ore_add_stripe_unit(struct ore_io_state *ios, unsigned *cur_pg, + added_len = bio_add_pc_page(q, per_dev->bio, pages[pg], + pglen, pgbase); + if (unlikely(pglen != added_len)) { +- ORE_DBGMSG("Failed bio_add_pc_page bi_vcnt=%u\n", +- per_dev->bio->bi_vcnt); ++ /* If bi_vcnt == bi_max then this is a SW BUG */ ++ ORE_DBGMSG("Failed bio_add_pc_page bi_vcnt=0x%x " ++ "bi_max=0x%x BIO_MAX=0x%x cur_len=0x%x\n", ++ per_dev->bio->bi_vcnt, ++ per_dev->bio->bi_max_vecs, ++ BIO_MAX_PAGES_KMALLOC, cur_len); + ret = -ENOMEM; + goto out; + } +@@ -1099,7 +1112,7 @@ int ore_truncate(struct ore_layout *layout, struct ore_components *oc, + size_attr->attr = g_attr_logical_length; + size_attr->attr.val_ptr = &size_attr->newsize; + +- ORE_DBGMSG("trunc(0x%llx) obj_offset=0x%llx dev=%d\n", ++ ORE_DBGMSG2("trunc(0x%llx) obj_offset=0x%llx dev=%d\n", + _LLU(oc->comps->obj.id), _LLU(obj_size), i); + ret = _truncate_mirrors(ios, i * ios->layout->mirrors_p1, + &size_attr->attr); +diff --git a/fs/hpfs/dir.c b/fs/hpfs/dir.c +index 2fa0089a02a8..46549c778001 100644 +--- a/fs/hpfs/dir.c ++++ b/fs/hpfs/dir.c +@@ -33,25 +33,27 @@ static loff_t hpfs_dir_lseek(struct file *filp, loff_t off, int whence) + if (whence == SEEK_DATA || whence == SEEK_HOLE) + return -EINVAL; + ++ mutex_lock(&i->i_mutex); + hpfs_lock(s); + + /*printk("dir lseek\n");*/ + if (new_off == 0 || new_off == 1 || new_off == 11 || new_off == 12 || new_off == 13) goto ok; +- mutex_lock(&i->i_mutex); + pos = ((loff_t) hpfs_de_as_down_as_possible(s, hpfs_inode->i_dno) << 4) + 1; + while (pos != new_off) { + if (map_pos_dirent(i, &pos, &qbh)) hpfs_brelse4(&qbh); + else goto fail; + if (pos == 12) goto fail; + } +- mutex_unlock(&i->i_mutex); ++ hpfs_add_pos(i, &filp->f_pos); + ok: ++ filp->f_pos = new_off; + hpfs_unlock(s); +- return filp->f_pos = new_off; +-fail: + mutex_unlock(&i->i_mutex); ++ return new_off; ++fail: + /*printk("illegal lseek: %016llx\n", new_off);*/ + hpfs_unlock(s); ++ mutex_unlock(&i->i_mutex); + return -ESPIPE; + } + +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index a7ea637bf215..d5faa264ecc2 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -6394,7 +6394,7 @@ nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle, + switch (err) { + case 0: + case -NFS4ERR_WRONGSEC: +- case -NFS4ERR_NOTSUPP: ++ case -ENOTSUPP: + goto out; + default: + err = nfs4_handle_exception(server, err, &exception); +@@ -6426,7 +6426,7 @@ nfs41_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle, + * Fall back on "guess and check" method if + * the server doesn't support SECINFO_NO_NAME + */ +- if (err == -NFS4ERR_WRONGSEC || err == -NFS4ERR_NOTSUPP) { ++ if (err == -NFS4ERR_WRONGSEC || err == -ENOTSUPP) { + err = nfs4_find_root_sec(server, fhandle, info); + goto out_freepage; + } +diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c +index c8ac9a1461c2..8cf722f2e2eb 100644 +--- a/fs/nfs/nfs4xdr.c ++++ b/fs/nfs/nfs4xdr.c +@@ -2955,7 +2955,8 @@ out_overflow: + return -EIO; + } + +-static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) ++static bool __decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected, ++ int *nfs_retval) + { + __be32 *p; + uint32_t opnum; +@@ -2965,19 +2966,32 @@ static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) + if (unlikely(!p)) + goto out_overflow; + opnum = be32_to_cpup(p++); +- if (opnum != expected) { +- dprintk("nfs: Server returned operation" +- " %d but we issued a request for %d\n", +- opnum, expected); +- return -EIO; +- } ++ if (unlikely(opnum != expected)) ++ goto out_bad_operation; + nfserr = be32_to_cpup(p); +- if (nfserr != NFS_OK) +- return nfs4_stat_to_errno(nfserr); +- return 0; ++ if (nfserr == NFS_OK) ++ *nfs_retval = 0; ++ else ++ *nfs_retval = nfs4_stat_to_errno(nfserr); ++ return true; ++out_bad_operation: ++ dprintk("nfs: Server returned operation" ++ " %d but we issued a request for %d\n", ++ opnum, expected); ++ *nfs_retval = -EREMOTEIO; ++ return false; + out_overflow: + print_overflow_msg(__func__, xdr); +- return -EIO; ++ *nfs_retval = -EIO; ++ return false; ++} ++ ++static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) ++{ ++ int retval; ++ ++ __decode_op_hdr(xdr, expected, &retval); ++ return retval; + } + + /* Dummy routine */ +@@ -4680,11 +4694,12 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) + uint32_t savewords, bmlen, i; + int status; + +- status = decode_op_hdr(xdr, OP_OPEN); +- if (status != -EIO) +- nfs_increment_open_seqid(status, res->seqid); +- if (!status) +- status = decode_stateid(xdr, &res->stateid); ++ if (!__decode_op_hdr(xdr, OP_OPEN, &status)) ++ return status; ++ nfs_increment_open_seqid(status, res->seqid); ++ if (status) ++ return status; ++ status = decode_stateid(xdr, &res->stateid); + if (unlikely(status)) + return status; + +diff --git a/include/linux/audit.h b/include/linux/audit.h +index 4f334d51b38b..acc4ff3702cf 100644 +--- a/include/linux/audit.h ++++ b/include/linux/audit.h +@@ -487,7 +487,7 @@ static inline void audit_syscall_exit(void *pt_regs) + { + if (unlikely(current->audit_context)) { + int success = is_syscall_success(pt_regs); +- int return_code = regs_return_value(pt_regs); ++ long return_code = regs_return_value(pt_regs); + + __audit_syscall_exit(success, return_code); + } +diff --git a/include/linux/sched.h b/include/linux/sched.h +index e132a2d24740..1c2470de8052 100644 +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -1237,6 +1237,7 @@ struct sched_entity { + struct sched_rt_entity { + struct list_head run_list; + unsigned long timeout; ++ unsigned long watchdog_stamp; + unsigned int time_slice; + int nr_cpus_allowed; + +diff --git a/include/scsi/osd_ore.h b/include/scsi/osd_ore.h +index a5f9b960dfc8..6ca3265a4dca 100644 +--- a/include/scsi/osd_ore.h ++++ b/include/scsi/osd_ore.h +@@ -102,6 +102,7 @@ struct ore_striping_info { + unsigned unit_off; + unsigned cur_pg; + unsigned cur_comp; ++ unsigned maxdevUnits; + }; + + struct ore_io_state; +diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c +index eff0b1e96331..32f0cb8f1fe8 100644 +--- a/kernel/time/timekeeping.c ++++ b/kernel/time/timekeeping.c +@@ -988,7 +988,8 @@ static void timekeeping_adjust(s64 offset) + * + * Returns the unconsumed cycles. + */ +-static cycle_t logarithmic_accumulation(cycle_t offset, int shift) ++static cycle_t logarithmic_accumulation(cycle_t offset, int shift, ++ unsigned int *clock_set) + { + u64 nsecps = (u64)NSEC_PER_SEC << timekeeper.shift; + u64 raw_nsecs; +@@ -1010,7 +1011,7 @@ static cycle_t logarithmic_accumulation(cycle_t offset, int shift) + timekeeper.xtime.tv_sec += leap; + timekeeper.wall_to_monotonic.tv_sec -= leap; + if (leap) +- clock_was_set_delayed(); ++ *clock_set = 1; + } + + /* Accumulate raw time */ +@@ -1042,6 +1043,7 @@ static void update_wall_time(void) + struct clocksource *clock; + cycle_t offset; + int shift = 0, maxshift; ++ unsigned int clock_set = 0; + unsigned long flags; + + write_seqlock_irqsave(&timekeeper.lock, flags); +@@ -1077,7 +1079,7 @@ static void update_wall_time(void) + maxshift = (64 - (ilog2(ntp_tick_length())+1)) - 1; + shift = min(shift, maxshift); + while (offset >= timekeeper.cycle_interval) { +- offset = logarithmic_accumulation(offset, shift); ++ offset = logarithmic_accumulation(offset, shift, &clock_set); + if(offset < timekeeper.cycle_interval<partial; + + if (page) { +- x = page->pobjects; ++ node = page_to_nid(page); ++ if (flags & SO_TOTAL) ++ WARN_ON_ONCE(1); ++ else if (flags & SO_OBJECTS) ++ WARN_ON_ONCE(1); ++ else ++ x = page->pages; + total += x; + nodes[node] += x; + } +diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c +index f21486a2ac48..0658fb926983 100644 +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -1331,9 +1331,13 @@ call_refreshresult(struct rpc_task *task) + task->tk_action = call_refresh; + switch (status) { + case 0: +- if (rpcauth_uptodatecred(task)) ++ if (rpcauth_uptodatecred(task)) { + task->tk_action = call_allocate; +- return; ++ return; ++ } ++ /* Use rate-limiting and a max number of retries if refresh ++ * had status 0 but failed to update the cred. ++ */ + case -ETIMEDOUT: + rpc_delay(task, 3*HZ); + case -EAGAIN: +diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c +index a7f61d52f05c..1249e17b61ff 100644 +--- a/security/selinux/ss/policydb.c ++++ b/security/selinux/ss/policydb.c +@@ -1914,7 +1914,19 @@ static int filename_trans_read(struct policydb *p, void *fp) + if (rc) + goto out; + +- hashtab_insert(p->filename_trans, ft, otype); ++ rc = hashtab_insert(p->filename_trans, ft, otype); ++ if (rc) { ++ /* ++ * Do not return -EEXIST to the caller, or the system ++ * will not boot. ++ */ ++ if (rc != -EEXIST) ++ goto out; ++ /* But free memory to avoid memory leak. */ ++ kfree(ft); ++ kfree(name); ++ kfree(otype); ++ } + } + hash_eval(p->filename_trans, "filenametr"); + return 0; +diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c +index ab2f682fd44c..00772661894c 100644 +--- a/tools/power/x86/turbostat/turbostat.c ++++ b/tools/power/x86/turbostat/turbostat.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + + #define MSR_TSC 0x10 + #define MSR_NEHALEM_PLATFORM_INFO 0xCE +@@ -932,7 +933,7 @@ void check_cpuid() + + eax = ebx = ecx = edx = 0; + +- asm("cpuid" : "=a" (max_level), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0)); ++ __get_cpuid(0, &max_level, &ebx, &ecx, &edx); + + if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e) + genuine_intel = 1; +@@ -941,7 +942,7 @@ void check_cpuid() + fprintf(stderr, "%.4s%.4s%.4s ", + (char *)&ebx, (char *)&edx, (char *)&ecx); + +- asm("cpuid" : "=a" (fms), "=c" (ecx), "=d" (edx) : "a" (1) : "ebx"); ++ __get_cpuid(1, &fms, &ebx, &ecx, &edx); + family = (fms >> 8) & 0xf; + model = (fms >> 4) & 0xf; + stepping = fms & 0xf; +@@ -963,7 +964,7 @@ void check_cpuid() + * This check is valid for both Intel and AMD. + */ + ebx = ecx = edx = 0; +- asm("cpuid" : "=a" (max_level), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x80000000)); ++ __get_cpuid(0x80000000, &max_level, &ebx, &ecx, &edx); + + if (max_level < 0x80000007) { + fprintf(stderr, "CPUID: no invariant TSC (max_level 0x%x)\n", max_level); +@@ -974,7 +975,7 @@ void check_cpuid() + * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8 + * this check is valid for both Intel and AMD + */ +- asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x80000007)); ++ __get_cpuid(0x80000007, &eax, &ebx, &ecx, &edx); + has_invariant_tsc = edx & (1 << 8); + + if (!has_invariant_tsc) { +@@ -987,7 +988,7 @@ void check_cpuid() + * this check is valid for both Intel and AMD + */ + +- asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x6)); ++ __get_cpuid(0x6, &eax, &ebx, &ecx, &edx); + has_aperf = ecx & (1 << 0); + if (!has_aperf) { + fprintf(stderr, "No APERF MSR\n"); diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.80-81.patch b/patch/kernel/sun8i-default/0001-patch-3.4.80-81.patch new file mode 100644 index 000000000..ccb2afc1c --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.80-81.patch @@ -0,0 +1,1108 @@ +diff --git a/Makefile b/Makefile +index 7b6c9ec4922b..5e1e1d6e0736 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 80 ++SUBLEVEL = 81 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c +index 0d39f2f4294a..e51fdc72cdc0 100644 +--- a/drivers/block/virtio_blk.c ++++ b/drivers/block/virtio_blk.c +@@ -21,8 +21,6 @@ struct workqueue_struct *virtblk_wq; + + struct virtio_blk + { +- spinlock_t lock; +- + struct virtio_device *vdev; + struct virtqueue *vq; + +@@ -69,7 +67,7 @@ static void blk_done(struct virtqueue *vq) + unsigned int len; + unsigned long flags; + +- spin_lock_irqsave(&vblk->lock, flags); ++ spin_lock_irqsave(vblk->disk->queue->queue_lock, flags); + while ((vbr = virtqueue_get_buf(vblk->vq, &len)) != NULL) { + int error; + +@@ -104,7 +102,7 @@ static void blk_done(struct virtqueue *vq) + } + /* In case queue is stopped waiting for more buffers. */ + blk_start_queue(vblk->disk->queue); +- spin_unlock_irqrestore(&vblk->lock, flags); ++ spin_unlock_irqrestore(vblk->disk->queue->queue_lock, flags); + } + + static bool do_req(struct request_queue *q, struct virtio_blk *vblk, +@@ -438,7 +436,6 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) + } + + INIT_LIST_HEAD(&vblk->reqs); +- spin_lock_init(&vblk->lock); + vblk->vdev = vdev; + vblk->sg_elems = sg_elems; + sg_init_table(vblk->sg, vblk->sg_elems); +@@ -463,7 +460,7 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) + goto out_mempool; + } + +- q = vblk->disk->queue = blk_init_queue(do_virtblk_request, &vblk->lock); ++ q = vblk->disk->queue = blk_init_queue(do_virtblk_request, NULL); + if (!q) { + err = -ENOMEM; + goto out_put_disk; +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index ba60f3c8f911..38c0a4720cc8 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1934,6 +1934,27 @@ ips_ping_for_i915_load(void) + } + } + ++static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) ++{ ++ struct apertures_struct *ap; ++ struct pci_dev *pdev = dev_priv->dev->pdev; ++ bool primary; ++ ++ ap = alloc_apertures(1); ++ if (!ap) ++ return; ++ ++ ap->ranges[0].base = dev_priv->dev->agp->base; ++ ap->ranges[0].size = ++ dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; ++ primary = ++ pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; ++ ++ remove_conflicting_framebuffers(ap, "inteldrmfb", primary); ++ ++ kfree(ap); ++} ++ + /** + * i915_driver_load - setup chip and create an initial config + * @dev: DRM device +@@ -1971,6 +1992,15 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + goto free_priv; + } + ++ dev_priv->mm.gtt = intel_gtt_get(); ++ if (!dev_priv->mm.gtt) { ++ DRM_ERROR("Failed to initialize GTT\n"); ++ ret = -ENODEV; ++ goto put_bridge; ++ } ++ ++ i915_kick_out_firmware_fb(dev_priv); ++ + pci_set_master(dev->pdev); + + /* overlay on gen2 is broken and can't address above 1G */ +@@ -1996,13 +2026,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + goto put_bridge; + } + +- dev_priv->mm.gtt = intel_gtt_get(); +- if (!dev_priv->mm.gtt) { +- DRM_ERROR("Failed to initialize GTT\n"); +- ret = -ENODEV; +- goto out_rmmap; +- } +- + agp_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; + + dev_priv->mm.gtt_mapping = +diff --git a/drivers/infiniband/hw/qib/qib_user_sdma.c b/drivers/infiniband/hw/qib/qib_user_sdma.c +index 82442085cbe6..573b4601d5b9 100644 +--- a/drivers/infiniband/hw/qib/qib_user_sdma.c ++++ b/drivers/infiniband/hw/qib/qib_user_sdma.c +@@ -284,8 +284,7 @@ static int qib_user_sdma_pin_pages(const struct qib_devdata *dd, + int j; + int ret; + +- ret = get_user_pages(current, current->mm, addr, +- npages, 0, 1, pages, NULL); ++ ret = get_user_pages_fast(addr, npages, 0, pages); + + if (ret != npages) { + int i; +@@ -830,10 +829,7 @@ int qib_user_sdma_writev(struct qib_ctxtdata *rcd, + while (dim) { + const int mxp = 8; + +- down_write(¤t->mm->mmap_sem); + ret = qib_user_sdma_queue_pkts(dd, pq, &list, iov, dim, mxp); +- up_write(¤t->mm->mmap_sem); +- + if (ret <= 0) + goto done_unlock; + else { +diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c +index a4b14a41cbf4..e2c2e1e2bd6f 100644 +--- a/drivers/input/mouse/synaptics.c ++++ b/drivers/input/mouse/synaptics.c +@@ -40,11 +40,28 @@ + * Note that newer firmware allows querying device for maximum useable + * coordinates. + */ ++#define XMIN 0 ++#define XMAX 6143 ++#define YMIN 0 ++#define YMAX 6143 + #define XMIN_NOMINAL 1472 + #define XMAX_NOMINAL 5472 + #define YMIN_NOMINAL 1408 + #define YMAX_NOMINAL 4448 + ++/* Size in bits of absolute position values reported by the hardware */ ++#define ABS_POS_BITS 13 ++ ++/* ++ * Any position values from the hardware above the following limits are ++ * treated as "wrapped around negative" values that have been truncated to ++ * the 13-bit reporting range of the hardware. These are just reasonable ++ * guesses and can be adjusted if hardware is found that operates outside ++ * of these parameters. ++ */ ++#define X_MAX_POSITIVE (((1 << ABS_POS_BITS) + XMAX) / 2) ++#define Y_MAX_POSITIVE (((1 << ABS_POS_BITS) + YMAX) / 2) ++ + /* + * Synaptics touchpads report the y coordinate from bottom to top, which is + * opposite from what userspace expects. +@@ -555,6 +572,12 @@ static int synaptics_parse_hw_state(const unsigned char buf[], + hw->right = (buf[0] & 0x02) ? 1 : 0; + } + ++ /* Convert wrap-around values to negative */ ++ if (hw->x > X_MAX_POSITIVE) ++ hw->x -= 1 << ABS_POS_BITS; ++ if (hw->y > Y_MAX_POSITIVE) ++ hw->y -= 1 << ABS_POS_BITS; ++ + return 0; + } + +diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig +index 10f122a3a856..da4dc255bc54 100644 +--- a/drivers/md/Kconfig ++++ b/drivers/md/Kconfig +@@ -185,8 +185,12 @@ config MD_FAULTY + + In unsure, say N. + ++config BLK_DEV_DM_BUILTIN ++ boolean ++ + config BLK_DEV_DM + tristate "Device mapper support" ++ select BLK_DEV_DM_BUILTIN + ---help--- + Device-mapper is a low level volume manager. It works by allowing + people to specify mappings for ranges of logical sectors. Various +diff --git a/drivers/md/Makefile b/drivers/md/Makefile +index 8b2e0dffe82e..4e87c544744d 100644 +--- a/drivers/md/Makefile ++++ b/drivers/md/Makefile +@@ -28,6 +28,7 @@ obj-$(CONFIG_MD_MULTIPATH) += multipath.o + obj-$(CONFIG_MD_FAULTY) += faulty.o + obj-$(CONFIG_BLK_DEV_MD) += md-mod.o + obj-$(CONFIG_BLK_DEV_DM) += dm-mod.o ++obj-$(CONFIG_BLK_DEV_DM_BUILTIN) += dm-builtin.o + obj-$(CONFIG_DM_BUFIO) += dm-bufio.o + obj-$(CONFIG_DM_CRYPT) += dm-crypt.o + obj-$(CONFIG_DM_DELAY) += dm-delay.o +diff --git a/drivers/md/dm-builtin.c b/drivers/md/dm-builtin.c +new file mode 100644 +index 000000000000..797daec490ed +--- /dev/null ++++ b/drivers/md/dm-builtin.c +@@ -0,0 +1,50 @@ ++#include "dm.h" ++ ++#include ++ ++/* ++ * The kobject release method must not be placed in the module itself, ++ * otherwise we are subject to module unload races. ++ * ++ * The release method is called when the last reference to the kobject is ++ * dropped. It may be called by any other kernel code that drops the last ++ * reference. ++ * ++ * The release method suffers from module unload race. We may prevent the ++ * module from being unloaded at the start of the release method (using ++ * increased module reference count or synchronizing against the release ++ * method), however there is no way to prevent the module from being ++ * unloaded at the end of the release method. ++ * ++ * If this code were placed in the dm module, the following race may ++ * happen: ++ * 1. Some other process takes a reference to dm kobject ++ * 2. The user issues ioctl function to unload the dm device ++ * 3. dm_sysfs_exit calls kobject_put, however the object is not released ++ * because of the other reference taken at step 1 ++ * 4. dm_sysfs_exit waits on the completion ++ * 5. The other process that took the reference in step 1 drops it, ++ * dm_kobject_release is called from this process ++ * 6. dm_kobject_release calls complete() ++ * 7. a reschedule happens before dm_kobject_release returns ++ * 8. dm_sysfs_exit continues, the dm device is unloaded, module reference ++ * count is decremented ++ * 9. The user unloads the dm module ++ * 10. The other process that was rescheduled in step 7 continues to run, ++ * it is now executing code in unloaded module, so it crashes ++ * ++ * Note that if the process that takes the foreign reference to dm kobject ++ * has a low priority and the system is sufficiently loaded with ++ * higher-priority processes that prevent the low-priority process from ++ * being scheduled long enough, this bug may really happen. ++ * ++ * In order to fix this module unload race, we place the release method ++ * into a helper code that is compiled directly into the kernel. ++ */ ++ ++void dm_kobject_release(struct kobject *kobj) ++{ ++ complete(dm_get_completion_from_kobject(kobj)); ++} ++ ++EXPORT_SYMBOL(dm_kobject_release); +diff --git a/drivers/md/dm-sysfs.c b/drivers/md/dm-sysfs.c +index e0cc5d6a9e46..c62c5ab6aed5 100644 +--- a/drivers/md/dm-sysfs.c ++++ b/drivers/md/dm-sysfs.c +@@ -79,11 +79,6 @@ static const struct sysfs_ops dm_sysfs_ops = { + .show = dm_attr_show, + }; + +-static void dm_kobject_release(struct kobject *kobj) +-{ +- complete(dm_get_completion_from_kobject(kobj)); +-} +- + /* + * dm kobject is embedded in mapped_device structure + * no need to define release function here +diff --git a/drivers/md/dm.c b/drivers/md/dm.c +index d26fddf7c1fb..0cf8c519d07e 100644 +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -191,11 +191,8 @@ struct mapped_device { + /* forced geometry settings */ + struct hd_geometry geometry; + +- /* sysfs handle */ +- struct kobject kobj; +- +- /* wait until the kobject is released */ +- struct completion kobj_completion; ++ /* kobject and completion */ ++ struct dm_kobject_holder kobj_holder; + + /* zero-length flush that will be cloned and submitted to targets */ + struct bio flush_bio; +@@ -1894,7 +1891,7 @@ static struct mapped_device *alloc_dev(int minor) + init_waitqueue_head(&md->wait); + INIT_WORK(&md->work, dm_wq_work); + init_waitqueue_head(&md->eventq); +- init_completion(&md->kobj_completion); ++ init_completion(&md->kobj_holder.completion); + + md->disk->major = _major; + md->disk->first_minor = minor; +@@ -2686,20 +2683,14 @@ struct gendisk *dm_disk(struct mapped_device *md) + + struct kobject *dm_kobject(struct mapped_device *md) + { +- return &md->kobj; ++ return &md->kobj_holder.kobj; + } + +-/* +- * struct mapped_device should not be exported outside of dm.c +- * so use this check to verify that kobj is part of md structure +- */ + struct mapped_device *dm_get_from_kobject(struct kobject *kobj) + { + struct mapped_device *md; + +- md = container_of(kobj, struct mapped_device, kobj); +- if (&md->kobj != kobj) +- return NULL; ++ md = container_of(kobj, struct mapped_device, kobj_holder.kobj); + + if (test_bit(DMF_FREEING, &md->flags) || + dm_deleting_md(md)) +@@ -2709,13 +2700,6 @@ struct mapped_device *dm_get_from_kobject(struct kobject *kobj) + return md; + } + +-struct completion *dm_get_completion_from_kobject(struct kobject *kobj) +-{ +- struct mapped_device *md = container_of(kobj, struct mapped_device, kobj); +- +- return &md->kobj_completion; +-} +- + int dm_suspended_md(struct mapped_device *md) + { + return test_bit(DMF_SUSPENDED, &md->flags); +diff --git a/drivers/md/dm.h b/drivers/md/dm.h +index 1174e9654882..9db80c92096a 100644 +--- a/drivers/md/dm.h ++++ b/drivers/md/dm.h +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + + /* + * Suspend feature flags +@@ -120,11 +121,25 @@ void dm_interface_exit(void); + /* + * sysfs interface + */ ++struct dm_kobject_holder { ++ struct kobject kobj; ++ struct completion completion; ++}; ++ ++static inline struct completion *dm_get_completion_from_kobject(struct kobject *kobj) ++{ ++ return &container_of(kobj, struct dm_kobject_holder, kobj)->completion; ++} ++ + int dm_sysfs_init(struct mapped_device *md); + void dm_sysfs_exit(struct mapped_device *md); + struct kobject *dm_kobject(struct mapped_device *md); + struct mapped_device *dm_get_from_kobject(struct kobject *kobj); +-struct completion *dm_get_completion_from_kobject(struct kobject *kobj); ++ ++/* ++ * The kobject helper ++ */ ++void dm_kobject_release(struct kobject *kobj); + + /* + * Targets for linear and striped mappings +diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c +index f286955331a2..a251efd783de 100644 +--- a/drivers/target/target_core_file.c ++++ b/drivers/target/target_core_file.c +@@ -133,21 +133,24 @@ static struct se_device *fd_create_virtdevice( + ret = PTR_ERR(dev_p); + goto fail; + } +-#if 0 +- if (di->no_create_file) +- flags = O_RDWR | O_LARGEFILE; +- else +- flags = O_RDWR | O_CREAT | O_LARGEFILE; +-#else +- flags = O_RDWR | O_CREAT | O_LARGEFILE; +-#endif +-/* flags |= O_DIRECT; */ + /* +- * If fd_buffered_io=1 has not been set explicitly (the default), +- * use O_SYNC to force FILEIO writes to disk. ++ * Use O_DSYNC by default instead of O_SYNC to forgo syncing ++ * of pure timestamp updates. ++ */ ++ flags = O_RDWR | O_CREAT | O_LARGEFILE | O_DSYNC; ++ /* ++ * Optionally allow fd_buffered_io=1 to be enabled for people ++ * who want use the fs buffer cache as an WriteCache mechanism. ++ * ++ * This means that in event of a hard failure, there is a risk ++ * of silent data-loss if the SCSI client has *not* performed a ++ * forced unit access (FUA) write, or issued SYNCHRONIZE_CACHE ++ * to write-out the entire device cache. + */ +- if (!(fd_dev->fbd_flags & FDBD_USE_BUFFERED_IO)) +- flags |= O_SYNC; ++ if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) { ++ pr_debug("FILEIO: Disabling O_DSYNC, using buffered FILEIO\n"); ++ flags &= ~O_DSYNC; ++ } + + file = filp_open(dev_p, flags, 0600); + if (IS_ERR(file)) { +@@ -215,6 +218,12 @@ static struct se_device *fd_create_virtdevice( + if (!dev) + goto fail; + ++ if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) { ++ pr_debug("FILEIO: Forcing setting of emulate_write_cache=1" ++ " with FDBD_HAS_BUFFERED_IO_WCE\n"); ++ dev->se_sub_dev->se_dev_attrib.emulate_write_cache = 1; ++ } ++ + fd_dev->fd_dev_id = fd_host->fd_host_dev_id_count++; + fd_dev->fd_queue_depth = dev->queue_depth; + +@@ -399,26 +408,6 @@ static void fd_emulate_sync_cache(struct se_task *task) + transport_complete_sync_cache(cmd, ret == 0); + } + +-/* +- * WRITE Force Unit Access (FUA) emulation on a per struct se_task +- * LBA range basis.. +- */ +-static void fd_emulate_write_fua(struct se_cmd *cmd, struct se_task *task) +-{ +- struct se_device *dev = cmd->se_dev; +- struct fd_dev *fd_dev = dev->dev_ptr; +- loff_t start = task->task_lba * dev->se_sub_dev->se_dev_attrib.block_size; +- loff_t end = start + task->task_size; +- int ret; +- +- pr_debug("FILEIO: FUA WRITE LBA: %llu, bytes: %u\n", +- task->task_lba, task->task_size); +- +- ret = vfs_fsync_range(fd_dev->fd_file, start, end, 1); +- if (ret != 0) +- pr_err("FILEIO: vfs_fsync_range() failed: %d\n", ret); +-} +- + static int fd_do_task(struct se_task *task) + { + struct se_cmd *cmd = task->task_se_cmd; +@@ -433,19 +422,21 @@ static int fd_do_task(struct se_task *task) + ret = fd_do_readv(task); + } else { + ret = fd_do_writev(task); +- ++ /* ++ * Perform implict vfs_fsync_range() for fd_do_writev() ops ++ * for SCSI WRITEs with Forced Unit Access (FUA) set. ++ * Allow this to happen independent of WCE=0 setting. ++ */ + if (ret > 0 && +- dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0 && + dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0 && + (cmd->se_cmd_flags & SCF_FUA)) { +- /* +- * We might need to be a bit smarter here +- * and return some sense data to let the initiator +- * know the FUA WRITE cache sync failed..? +- */ +- fd_emulate_write_fua(cmd, task); +- } ++ struct fd_dev *fd_dev = dev->dev_ptr; ++ loff_t start = task->task_lba * ++ dev->se_sub_dev->se_dev_attrib.block_size; ++ loff_t end = start + task->task_size; + ++ vfs_fsync_range(fd_dev->fd_file, start, end, 1); ++ } + } + + if (ret < 0) { +@@ -544,7 +535,7 @@ static ssize_t fd_set_configfs_dev_params( + pr_debug("FILEIO: Using buffered I/O" + " operations for struct fd_dev\n"); + +- fd_dev->fbd_flags |= FDBD_USE_BUFFERED_IO; ++ fd_dev->fbd_flags |= FDBD_HAS_BUFFERED_IO_WCE; + break; + default: + break; +@@ -579,8 +570,8 @@ static ssize_t fd_show_configfs_dev_params( + bl = sprintf(b + bl, "TCM FILEIO ID: %u", fd_dev->fd_dev_id); + bl += sprintf(b + bl, " File: %s Size: %llu Mode: %s\n", + fd_dev->fd_dev_name, fd_dev->fd_dev_size, +- (fd_dev->fbd_flags & FDBD_USE_BUFFERED_IO) ? +- "Buffered" : "Synchronous"); ++ (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) ? ++ "Buffered-WCE" : "O_DSYNC"); + return bl; + } + +diff --git a/drivers/target/target_core_file.h b/drivers/target/target_core_file.h +index 59e6e73106c2..6b1b6a979a10 100644 +--- a/drivers/target/target_core_file.h ++++ b/drivers/target/target_core_file.h +@@ -18,7 +18,7 @@ struct fd_request { + + #define FBDF_HAS_PATH 0x01 + #define FBDF_HAS_SIZE 0x02 +-#define FDBD_USE_BUFFERED_IO 0x04 ++#define FDBD_HAS_BUFFERED_IO_WCE 0x04 + + struct fd_dev { + u32 fbd_flags; +diff --git a/fs/buffer.c b/fs/buffer.c +index 18669e92b676..9bf31ac982e1 100644 +--- a/fs/buffer.c ++++ b/fs/buffer.c +@@ -613,14 +613,16 @@ EXPORT_SYMBOL(mark_buffer_dirty_inode); + static void __set_page_dirty(struct page *page, + struct address_space *mapping, int warn) + { +- spin_lock_irq(&mapping->tree_lock); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&mapping->tree_lock, flags); + if (page->mapping) { /* Race with truncate? */ + WARN_ON_ONCE(warn && !PageUptodate(page)); + account_page_dirtied(page, mapping); + radix_tree_tag_set(&mapping->page_tree, + page_index(page), PAGECACHE_TAG_DIRTY); + } +- spin_unlock_irq(&mapping->tree_lock); ++ spin_unlock_irqrestore(&mapping->tree_lock, flags); + __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); + } + +diff --git a/fs/nfs/write.c b/fs/nfs/write.c +index c07462320f6b..da8fd94fcd93 100644 +--- a/fs/nfs/write.c ++++ b/fs/nfs/write.c +@@ -1751,12 +1751,12 @@ int __init nfs_init_writepagecache(void) + nfs_wdata_mempool = mempool_create_slab_pool(MIN_POOL_WRITE, + nfs_wdata_cachep); + if (nfs_wdata_mempool == NULL) +- return -ENOMEM; ++ goto out_destroy_write_cache; + + nfs_commit_mempool = mempool_create_slab_pool(MIN_POOL_COMMIT, + nfs_wdata_cachep); + if (nfs_commit_mempool == NULL) +- return -ENOMEM; ++ goto out_destroy_write_mempool; + + /* + * NFS congestion size, scale with available memory. +@@ -1779,6 +1779,12 @@ int __init nfs_init_writepagecache(void) + nfs_congestion_kb = 256*1024; + + return 0; ++ ++out_destroy_write_mempool: ++ mempool_destroy(nfs_wdata_mempool); ++out_destroy_write_cache: ++ kmem_cache_destroy(nfs_wdata_cachep); ++ return -ENOMEM; + } + + void nfs_destroy_writepagecache(void) +diff --git a/include/linux/sched.h b/include/linux/sched.h +index 1c2470de8052..8cd5cb80223c 100644 +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -144,6 +144,7 @@ extern unsigned long this_cpu_load(void); + + + extern void calc_global_load(unsigned long ticks); ++extern void update_cpu_load_nohz(void); + + extern unsigned long get_parent_ip(unsigned long addr); + +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index 7522816cd7f6..94f132775d05 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -692,8 +692,6 @@ int tg_nop(struct task_group *tg, void *data) + } + #endif + +-void update_cpu_load(struct rq *this_rq); +- + static void set_load_weight(struct task_struct *p) + { + int prio = p->static_prio - MAX_RT_PRIO; +@@ -2620,22 +2618,13 @@ decay_load_missed(unsigned long load, unsigned long missed_updates, int idx) + * scheduler tick (TICK_NSEC). With tickless idle this will not be called + * every tick. We fix it up based on jiffies. + */ +-void update_cpu_load(struct rq *this_rq) ++static void __update_cpu_load(struct rq *this_rq, unsigned long this_load, ++ unsigned long pending_updates) + { +- unsigned long this_load = this_rq->load.weight; +- unsigned long curr_jiffies = jiffies; +- unsigned long pending_updates; + int i, scale; + + this_rq->nr_load_updates++; + +- /* Avoid repeated calls on same jiffy, when moving in and out of idle */ +- if (curr_jiffies == this_rq->last_load_update_tick) +- return; +- +- pending_updates = curr_jiffies - this_rq->last_load_update_tick; +- this_rq->last_load_update_tick = curr_jiffies; +- + /* Update our load: */ + this_rq->cpu_load[0] = this_load; /* Fasttrack for idx 0 */ + for (i = 1, scale = 2; i < CPU_LOAD_IDX_MAX; i++, scale += scale) { +@@ -2660,9 +2649,78 @@ void update_cpu_load(struct rq *this_rq) + sched_avg_update(this_rq); + } + ++#ifdef CONFIG_NO_HZ ++/* ++ * There is no sane way to deal with nohz on smp when using jiffies because the ++ * cpu doing the jiffies update might drift wrt the cpu doing the jiffy reading ++ * causing off-by-one errors in observed deltas; {0,2} instead of {1,1}. ++ * ++ * Therefore we cannot use the delta approach from the regular tick since that ++ * would seriously skew the load calculation. However we'll make do for those ++ * updates happening while idle (nohz_idle_balance) or coming out of idle ++ * (tick_nohz_idle_exit). ++ * ++ * This means we might still be one tick off for nohz periods. ++ */ ++ ++/* ++ * Called from nohz_idle_balance() to update the load ratings before doing the ++ * idle balance. ++ */ ++void update_idle_cpu_load(struct rq *this_rq) ++{ ++ unsigned long curr_jiffies = ACCESS_ONCE(jiffies); ++ unsigned long load = this_rq->load.weight; ++ unsigned long pending_updates; ++ ++ /* ++ * bail if there's load or we're actually up-to-date. ++ */ ++ if (load || curr_jiffies == this_rq->last_load_update_tick) ++ return; ++ ++ pending_updates = curr_jiffies - this_rq->last_load_update_tick; ++ this_rq->last_load_update_tick = curr_jiffies; ++ ++ __update_cpu_load(this_rq, load, pending_updates); ++} ++ ++/* ++ * Called from tick_nohz_idle_exit() -- try and fix up the ticks we missed. ++ */ ++void update_cpu_load_nohz(void) ++{ ++ struct rq *this_rq = this_rq(); ++ unsigned long curr_jiffies = ACCESS_ONCE(jiffies); ++ unsigned long pending_updates; ++ ++ if (curr_jiffies == this_rq->last_load_update_tick) ++ return; ++ ++ raw_spin_lock(&this_rq->lock); ++ pending_updates = curr_jiffies - this_rq->last_load_update_tick; ++ if (pending_updates) { ++ this_rq->last_load_update_tick = curr_jiffies; ++ /* ++ * We were idle, this means load 0, the current load might be ++ * !0 due to remote wakeups and the sort. ++ */ ++ __update_cpu_load(this_rq, 0, pending_updates); ++ } ++ raw_spin_unlock(&this_rq->lock); ++} ++#endif /* CONFIG_NO_HZ */ ++ ++/* ++ * Called from scheduler_tick() ++ */ + static void update_cpu_load_active(struct rq *this_rq) + { +- update_cpu_load(this_rq); ++ /* ++ * See the mess around update_idle_cpu_load() / update_cpu_load_nohz(). ++ */ ++ this_rq->last_load_update_tick = jiffies; ++ __update_cpu_load(this_rq, this_rq->load.weight, 1); + + calc_load_account_active(this_rq); + } +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 93be350c9b63..dd33c9fd8009 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -5042,7 +5042,7 @@ static void nohz_idle_balance(int this_cpu, enum cpu_idle_type idle) + + raw_spin_lock_irq(&this_rq->lock); + update_rq_clock(this_rq); +- update_cpu_load(this_rq); ++ update_idle_cpu_load(this_rq); + raw_spin_unlock_irq(&this_rq->lock); + + rebalance_domains(balance_cpu, CPU_IDLE); +diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h +index a70d8908a6d3..4a5e7398d77b 100644 +--- a/kernel/sched/sched.h ++++ b/kernel/sched/sched.h +@@ -873,7 +873,7 @@ extern void resched_cpu(int cpu); + extern struct rt_bandwidth def_rt_bandwidth; + extern void init_rt_bandwidth(struct rt_bandwidth *rt_b, u64 period, u64 runtime); + +-extern void update_cpu_load(struct rq *this_rq); ++extern void update_idle_cpu_load(struct rq *this_rq); + + #ifdef CONFIG_CGROUP_CPUACCT + #include +diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c +index a1e079536a71..638dadf6295f 100644 +--- a/kernel/time/tick-sched.c ++++ b/kernel/time/tick-sched.c +@@ -582,6 +582,7 @@ void tick_nohz_idle_exit(void) + /* Update jiffies first */ + select_nohz_load_balancer(0); + tick_do_update_jiffies64(now); ++ update_cpu_load_nohz(); + + #ifndef CONFIG_VIRT_CPU_ACCOUNTING + /* +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index f0e76e93aee5..5efdddf04b15 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -222,6 +222,29 @@ static void update_global_ops(void) + global_ops.func = func; + } + ++static void ftrace_sync(struct work_struct *work) ++{ ++ /* ++ * This function is just a stub to implement a hard force ++ * of synchronize_sched(). This requires synchronizing ++ * tasks even in userspace and idle. ++ * ++ * Yes, function tracing is rude. ++ */ ++} ++ ++static void ftrace_sync_ipi(void *data) ++{ ++ /* Probably not needed, but do it anyway */ ++ smp_rmb(); ++} ++ ++#ifdef CONFIG_FUNCTION_GRAPH_TRACER ++static void update_function_graph_func(void); ++#else ++static inline void update_function_graph_func(void) { } ++#endif ++ + static void update_ftrace_function(void) + { + ftrace_func_t func; +@@ -240,6 +263,8 @@ static void update_ftrace_function(void) + else + func = ftrace_ops_list_func; + ++ update_function_graph_func(); ++ + #ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST + ftrace_trace_function = func; + #else +@@ -359,16 +384,6 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops) + } else if (ops->flags & FTRACE_OPS_FL_CONTROL) { + ret = remove_ftrace_list_ops(&ftrace_control_list, + &control_ops, ops); +- if (!ret) { +- /* +- * The ftrace_ops is now removed from the list, +- * so there'll be no new users. We must ensure +- * all current users are done before we free +- * the control data. +- */ +- synchronize_sched(); +- control_ops_free(ops); +- } + } else + ret = remove_ftrace_ops(&ftrace_ops_list, ops); + +@@ -378,13 +393,6 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops) + if (ftrace_enabled) + update_ftrace_function(); + +- /* +- * Dynamic ops may be freed, we must make sure that all +- * callers are done before leaving this function. +- */ +- if (ops->flags & FTRACE_OPS_FL_DYNAMIC) +- synchronize_sched(); +- + return 0; + } + +@@ -2008,10 +2016,41 @@ static int ftrace_shutdown(struct ftrace_ops *ops, int command) + command |= FTRACE_UPDATE_TRACE_FUNC; + } + +- if (!command || !ftrace_enabled) ++ if (!command || !ftrace_enabled) { ++ /* ++ * If these are control ops, they still need their ++ * per_cpu field freed. Since, function tracing is ++ * not currently active, we can just free them ++ * without synchronizing all CPUs. ++ */ ++ if (ops->flags & FTRACE_OPS_FL_CONTROL) ++ control_ops_free(ops); + return 0; ++ } + + ftrace_run_update_code(command); ++ ++ /* ++ * Dynamic ops may be freed, we must make sure that all ++ * callers are done before leaving this function. ++ * The same goes for freeing the per_cpu data of the control ++ * ops. ++ * ++ * Again, normal synchronize_sched() is not good enough. ++ * We need to do a hard force of sched synchronization. ++ * This is because we use preempt_disable() to do RCU, but ++ * the function tracers can be called where RCU is not watching ++ * (like before user_exit()). We can not rely on the RCU ++ * infrastructure to do the synchronization, thus we must do it ++ * ourselves. ++ */ ++ if (ops->flags & (FTRACE_OPS_FL_DYNAMIC | FTRACE_OPS_FL_CONTROL)) { ++ schedule_on_each_cpu(ftrace_sync); ++ ++ if (ops->flags & FTRACE_OPS_FL_CONTROL) ++ control_ops_free(ops); ++ } ++ + return 0; + } + +@@ -4404,6 +4443,7 @@ int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace) + trace_func_graph_ret_t ftrace_graph_return = + (trace_func_graph_ret_t)ftrace_stub; + trace_func_graph_ent_t ftrace_graph_entry = ftrace_graph_entry_stub; ++static trace_func_graph_ent_t __ftrace_graph_entry = ftrace_graph_entry_stub; + + /* Try to assign a return stack array on FTRACE_RETSTACK_ALLOC_SIZE tasks. */ + static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list) +@@ -4544,6 +4584,30 @@ static struct ftrace_ops fgraph_ops __read_mostly = { + .flags = FTRACE_OPS_FL_GLOBAL, + }; + ++static int ftrace_graph_entry_test(struct ftrace_graph_ent *trace) ++{ ++ if (!ftrace_ops_test(&global_ops, trace->func)) ++ return 0; ++ return __ftrace_graph_entry(trace); ++} ++ ++/* ++ * The function graph tracer should only trace the functions defined ++ * by set_ftrace_filter and set_ftrace_notrace. If another function ++ * tracer ops is registered, the graph tracer requires testing the ++ * function against the global ops, and not just trace any function ++ * that any ftrace_ops registered. ++ */ ++static void update_function_graph_func(void) ++{ ++ if (ftrace_ops_list == &ftrace_list_end || ++ (ftrace_ops_list == &global_ops && ++ global_ops.next == &ftrace_list_end)) ++ ftrace_graph_entry = __ftrace_graph_entry; ++ else ++ ftrace_graph_entry = ftrace_graph_entry_test; ++} ++ + int register_ftrace_graph(trace_func_graph_ret_t retfunc, + trace_func_graph_ent_t entryfunc) + { +@@ -4568,7 +4632,16 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc, + } + + ftrace_graph_return = retfunc; +- ftrace_graph_entry = entryfunc; ++ ++ /* ++ * Update the indirect function to the entryfunc, and the ++ * function that gets called to the entry_test first. Then ++ * call the update fgraph entry function to determine if ++ * the entryfunc should be called directly or not. ++ */ ++ __ftrace_graph_entry = entryfunc; ++ ftrace_graph_entry = ftrace_graph_entry_test; ++ update_function_graph_func(); + + ret = ftrace_startup(&fgraph_ops, FTRACE_START_FUNC_RET); + +@@ -4587,6 +4660,7 @@ void unregister_ftrace_graph(void) + ftrace_graph_active--; + ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub; + ftrace_graph_entry = ftrace_graph_entry_stub; ++ __ftrace_graph_entry = ftrace_graph_entry_stub; + ftrace_shutdown(&fgraph_ops, FTRACE_STOP_FUNC_RET); + unregister_pm_notifier(&ftrace_suspend_notifier); + unregister_trace_sched_switch(ftrace_graph_probe_sched_switch, NULL); +diff --git a/lib/Makefile b/lib/Makefile +index 18515f0267c4..801c567b9e4b 100644 +--- a/lib/Makefile ++++ b/lib/Makefile +@@ -41,6 +41,7 @@ obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o + lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o + lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o + ++GCOV_PROFILE_hweight.o := n + CFLAGS_hweight.o = $(subst $(quote),,$(CONFIG_ARCH_HWEIGHT_CFLAGS)) + obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o + +diff --git a/lib/vsprintf.c b/lib/vsprintf.c +index 73e2c45acfdb..cd0aab7e6aa7 100644 +--- a/lib/vsprintf.c ++++ b/lib/vsprintf.c +@@ -926,7 +926,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, + * %pK cannot be used in IRQ context because its test + * for CAP_SYSLOG would be meaningless. + */ +- if (in_irq() || in_serving_softirq() || in_nmi()) { ++ if (kptr_restrict && (in_irq() || in_serving_softirq() || ++ in_nmi())) { + if (spec.field_width == -1) + spec.field_width = 2 * sizeof(void *); + return string(buf, end, "pK-error", spec); +diff --git a/mm/internal.h b/mm/internal.h +index 2189af491783..0c26b5e6d41d 100644 +--- a/mm/internal.h ++++ b/mm/internal.h +@@ -344,6 +344,7 @@ + extern u64 hwpoison_filter_flags_value; + extern u64 hwpoison_filter_memcg; + extern u32 hwpoison_filter_enable; ++extern void set_pageblock_order(void); + /* The ALLOC_WMARK bits are used as an index to zone->watermark */ + #define ALLOC_WMARK_MIN WMARK_MIN + #define ALLOC_WMARK_LOW WMARK_LOW +diff --git a/mm/page-writeback.c b/mm/page-writeback.c +index 3b15e2a147a2..2a13b7997ac6 100644 +--- a/mm/page-writeback.c ++++ b/mm/page-writeback.c +@@ -1993,11 +1993,12 @@ int __set_page_dirty_nobuffers(struct page *page) + if (!TestSetPageDirty(page)) { + struct address_space *mapping = page_mapping(page); + struct address_space *mapping2; ++ unsigned long flags; + + if (!mapping) + return 1; + +- spin_lock_irq(&mapping->tree_lock); ++ spin_lock_irqsave(&mapping->tree_lock, flags); + mapping2 = page_mapping(page); + if (mapping2) { /* Race with truncate? */ + BUG_ON(mapping2 != mapping); +@@ -2006,7 +2007,7 @@ int __set_page_dirty_nobuffers(struct page *page) + radix_tree_tag_set(&mapping->page_tree, + page_index(page), PAGECACHE_TAG_DIRTY); + } +- spin_unlock_irq(&mapping->tree_lock); ++ spin_unlock_irqrestore(&mapping->tree_lock, flags); + if (mapping->host) { + /* !PageAnon && !swapper_space */ + __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index 508822e1082a..39d530a425b5 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -4254,25 +4254,24 @@ static inline void setup_usemap(struct pglist_data *pgdat, struct zone *zone, + + #ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE + +-/* Return a sensible default order for the pageblock size. */ +-static inline int pageblock_default_order(void) +-{ +- if (HPAGE_SHIFT > PAGE_SHIFT) +- return HUGETLB_PAGE_ORDER; +- +- return MAX_ORDER-1; +-} +- + /* Initialise the number of pages represented by NR_PAGEBLOCK_BITS */ +-static inline void __init set_pageblock_order(unsigned int order) ++void __init set_pageblock_order(void) + { ++ unsigned int order; ++ + /* Check that pageblock_nr_pages has not already been setup */ + if (pageblock_order) + return; + ++ if (HPAGE_SHIFT > PAGE_SHIFT) ++ order = HUGETLB_PAGE_ORDER; ++ else ++ order = MAX_ORDER - 1; ++ + /* + * Assume the largest contiguous order of interest is a huge page. +- * This value may be variable depending on boot parameters on IA64 ++ * This value may be variable depending on boot parameters on IA64 and ++ * powerpc. + */ + pageblock_order = order; + } +@@ -4280,15 +4279,13 @@ static inline void __init set_pageblock_order(unsigned int order) + + /* + * When CONFIG_HUGETLB_PAGE_SIZE_VARIABLE is not set, set_pageblock_order() +- * and pageblock_default_order() are unused as pageblock_order is set +- * at compile-time. See include/linux/pageblock-flags.h for the values of +- * pageblock_order based on the kernel config ++ * is unused as pageblock_order is set at compile-time. See ++ * include/linux/pageblock-flags.h for the values of pageblock_order based on ++ * the kernel config + */ +-static inline int pageblock_default_order(unsigned int order) ++void __init set_pageblock_order(void) + { +- return MAX_ORDER-1; + } +-#define set_pageblock_order(x) do {} while (0) + + #endif /* CONFIG_HUGETLB_PAGE_SIZE_VARIABLE */ + +@@ -4376,7 +4373,7 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat, + if (!size) + continue; + +- set_pageblock_order(pageblock_default_order()); ++ set_pageblock_order(); + setup_usemap(pgdat, zone, zone_start_pfn, size); + ret = init_currently_empty_zone(zone, zone_start_pfn, + size, MEMMAP_EARLY); +diff --git a/mm/sparse.c b/mm/sparse.c +index 290dba25a7ed..42935b5545a0 100644 +--- a/mm/sparse.c ++++ b/mm/sparse.c +@@ -486,6 +486,9 @@ void __init sparse_init(void) + struct page **map_map; + #endif + ++ /* Setup pageblock_order for HUGETLB_PAGE_SIZE_VARIABLE */ ++ set_pageblock_order(); ++ + /* + * map is using big page (aka 2M in x86 64 bit) + * usemap is less one page (aka 24 bytes) +diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c +index 9f614b4e365f..272407c00ede 100644 +--- a/virt/kvm/irq_comm.c ++++ b/virt/kvm/irq_comm.c +@@ -318,6 +318,7 @@ static int setup_routing_entry(struct kvm_irq_routing_table *rt, + */ + hlist_for_each_entry(ei, n, &rt->map[ue->gsi], link) + if (ei->type == KVM_IRQ_ROUTING_MSI || ++ ue->type == KVM_IRQ_ROUTING_MSI || + ue->u.irqchip.irqchip == ei->irqchip.irqchip) + return r; + diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.81-82.patch b/patch/kernel/sun8i-default/0001-patch-3.4.81-82.patch new file mode 100644 index 000000000..21da5716c --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.81-82.patch @@ -0,0 +1,633 @@ +diff --git a/Makefile b/Makefile +index 5e1e1d6e0736..ee80efa38844 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 81 ++SUBLEVEL = 82 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S +index 99348c0eaa41..78be2459c9a1 100644 +--- a/arch/s390/kernel/head64.S ++++ b/arch/s390/kernel/head64.S +@@ -61,7 +61,7 @@ ENTRY(startup_continue) + .quad 0 # cr12: tracing off + .quad 0 # cr13: home space segment table + .quad 0xc0000000 # cr14: machine check handling off +- .quad 0 # cr15: linkage stack operations ++ .quad .Llinkage_stack # cr15: linkage stack operations + .Lpcmsk:.quad 0x0000000180000000 + .L4malign:.quad 0xffffffffffc00000 + .Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8 +@@ -69,12 +69,15 @@ ENTRY(startup_continue) + .Lparmaddr: + .quad PARMAREA + .align 64 +-.Lduct: .long 0,0,0,0,.Lduald,0,0,0 ++.Lduct: .long 0,.Laste,.Laste,0,.Lduald,0,0,0 + .long 0,0,0,0,0,0,0,0 ++.Laste: .quad 0,0xffffffffffffffff,0,0,0,0,0,0 + .align 128 + .Lduald:.rept 8 + .long 0x80000000,0,0,0 # invalid access-list entries + .endr ++.Llinkage_stack: ++ .long 0,0,0x89000000,0,0,0,0x8a000000,0 + + ENTRY(_ehead) + +diff --git a/arch/s390/mm/page-states.c b/arch/s390/mm/page-states.c +index a90d45e9dfb0..27c50f4d90cb 100644 +--- a/arch/s390/mm/page-states.c ++++ b/arch/s390/mm/page-states.c +@@ -12,6 +12,8 @@ + #include + #include + #include ++#include ++#include + + #define ESSA_SET_STABLE 1 + #define ESSA_SET_UNUSED 2 +@@ -41,6 +43,14 @@ void __init cmma_init(void) + + if (!cmma_flag) + return; ++ /* ++ * Disable CMM for dump, otherwise the tprot based memory ++ * detection can fail because of unstable pages. ++ */ ++ if (OLDMEM_BASE || ipl_info.type == IPL_TYPE_FCP_DUMP) { ++ cmma_flag = 0; ++ return; ++ } + asm volatile( + " .insn rrf,0xb9ab0000,%1,%1,0,0\n" + "0: la %0,0\n" +diff --git a/block/blk-lib.c b/block/blk-lib.c +index 2b461b496a78..36751e211bb8 100644 +--- a/block/blk-lib.c ++++ b/block/blk-lib.c +@@ -101,6 +101,14 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, + + atomic_inc(&bb.done); + submit_bio(type, bio); ++ ++ /* ++ * We can loop for a long time in here, if someone does ++ * full device discards (like mkfs). Be nice and allow ++ * us to schedule out to avoid softlocking if preempt ++ * is disabled. ++ */ ++ cond_resched(); + } + + /* Wait for bios in-flight */ +diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c +index 4e86393a09cf..a81cdd7b9d83 100644 +--- a/drivers/block/xen-blkfront.c ++++ b/drivers/block/xen-blkfront.c +@@ -1303,13 +1303,16 @@ static void blkback_changed(struct xenbus_device *dev, + case XenbusStateReconfiguring: + case XenbusStateReconfigured: + case XenbusStateUnknown: +- case XenbusStateClosed: + break; + + case XenbusStateConnected: + blkfront_connect(info); + break; + ++ case XenbusStateClosed: ++ if (dev->state == XenbusStateClosed) ++ break; ++ /* Missed the backend's Closing state -- fallthrough */ + case XenbusStateClosing: + blkfront_closing(info); + break; +diff --git a/drivers/char/raw.c b/drivers/char/raw.c +index 54a3a6d09819..59596692df3e 100644 +--- a/drivers/char/raw.c ++++ b/drivers/char/raw.c +@@ -190,7 +190,7 @@ static int bind_get(int number, dev_t *dev) + struct raw_device_data *rawdev; + struct block_device *bdev; + +- if (number <= 0 || number >= MAX_RAW_MINORS) ++ if (number <= 0 || number >= max_raw_minors) + return -EINVAL; + + rawdev = &raw_devices[number]; +diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c +index 060b96064469..d25205309d45 100644 +--- a/drivers/infiniband/hw/qib/qib_iba7322.c ++++ b/drivers/infiniband/hw/qib/qib_iba7322.c +@@ -2279,6 +2279,11 @@ static int qib_7322_bringup_serdes(struct qib_pportdata *ppd) + qib_write_kreg_port(ppd, krp_ibcctrl_a, ppd->cpspec->ibcctrl_a); + qib_write_kreg(dd, kr_scratch, 0ULL); + ++ /* ensure previous Tx parameters are not still forced */ ++ qib_write_kreg_port(ppd, krp_tx_deemph_override, ++ SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, ++ reset_tx_deemphasis_override)); ++ + if (qib_compat_ddr_negotiate) { + ppd->cpspec->ibdeltainprog = 1; + ppd->cpspec->ibsymsnap = read_7322_creg32_port(ppd, +diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c +index 3aed841ce84b..17b918d3d6b3 100644 +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -4678,23 +4678,43 @@ raid5_size(struct mddev *mddev, sector_t sectors, int raid_disks) + return sectors * (raid_disks - conf->max_degraded); + } + ++static void free_scratch_buffer(struct r5conf *conf, struct raid5_percpu *percpu) ++{ ++ safe_put_page(percpu->spare_page); ++ kfree(percpu->scribble); ++ percpu->spare_page = NULL; ++ percpu->scribble = NULL; ++} ++ ++static int alloc_scratch_buffer(struct r5conf *conf, struct raid5_percpu *percpu) ++{ ++ if (conf->level == 6 && !percpu->spare_page) ++ percpu->spare_page = alloc_page(GFP_KERNEL); ++ if (!percpu->scribble) ++ percpu->scribble = kmalloc(conf->scribble_len, GFP_KERNEL); ++ ++ if (!percpu->scribble || (conf->level == 6 && !percpu->spare_page)) { ++ free_scratch_buffer(conf, percpu); ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ + static void raid5_free_percpu(struct r5conf *conf) + { +- struct raid5_percpu *percpu; + unsigned long cpu; + + if (!conf->percpu) + return; + +- get_online_cpus(); +- for_each_possible_cpu(cpu) { +- percpu = per_cpu_ptr(conf->percpu, cpu); +- safe_put_page(percpu->spare_page); +- kfree(percpu->scribble); +- } + #ifdef CONFIG_HOTPLUG_CPU + unregister_cpu_notifier(&conf->cpu_notify); + #endif ++ ++ get_online_cpus(); ++ for_each_possible_cpu(cpu) ++ free_scratch_buffer(conf, per_cpu_ptr(conf->percpu, cpu)); + put_online_cpus(); + + free_percpu(conf->percpu); +@@ -4720,15 +4740,7 @@ static int raid456_cpu_notify(struct notifier_block *nfb, unsigned long action, + switch (action) { + case CPU_UP_PREPARE: + case CPU_UP_PREPARE_FROZEN: +- if (conf->level == 6 && !percpu->spare_page) +- percpu->spare_page = alloc_page(GFP_KERNEL); +- if (!percpu->scribble) +- percpu->scribble = kmalloc(conf->scribble_len, GFP_KERNEL); +- +- if (!percpu->scribble || +- (conf->level == 6 && !percpu->spare_page)) { +- safe_put_page(percpu->spare_page); +- kfree(percpu->scribble); ++ if (alloc_scratch_buffer(conf, percpu)) { + pr_err("%s: failed memory allocation for cpu%ld\n", + __func__, cpu); + return notifier_from_errno(-ENOMEM); +@@ -4736,10 +4748,7 @@ static int raid456_cpu_notify(struct notifier_block *nfb, unsigned long action, + break; + case CPU_DEAD: + case CPU_DEAD_FROZEN: +- safe_put_page(percpu->spare_page); +- kfree(percpu->scribble); +- percpu->spare_page = NULL; +- percpu->scribble = NULL; ++ free_scratch_buffer(conf, per_cpu_ptr(conf->percpu, cpu)); + break; + default: + break; +@@ -4751,40 +4760,29 @@ static int raid456_cpu_notify(struct notifier_block *nfb, unsigned long action, + static int raid5_alloc_percpu(struct r5conf *conf) + { + unsigned long cpu; +- struct page *spare_page; +- struct raid5_percpu __percpu *allcpus; +- void *scribble; +- int err; ++ int err = 0; + +- allcpus = alloc_percpu(struct raid5_percpu); +- if (!allcpus) ++ conf->percpu = alloc_percpu(struct raid5_percpu); ++ if (!conf->percpu) + return -ENOMEM; +- conf->percpu = allcpus; ++ ++#ifdef CONFIG_HOTPLUG_CPU ++ conf->cpu_notify.notifier_call = raid456_cpu_notify; ++ conf->cpu_notify.priority = 0; ++ err = register_cpu_notifier(&conf->cpu_notify); ++ if (err) ++ return err; ++#endif + + get_online_cpus(); +- err = 0; + for_each_present_cpu(cpu) { +- if (conf->level == 6) { +- spare_page = alloc_page(GFP_KERNEL); +- if (!spare_page) { +- err = -ENOMEM; +- break; +- } +- per_cpu_ptr(conf->percpu, cpu)->spare_page = spare_page; +- } +- scribble = kmalloc(conf->scribble_len, GFP_KERNEL); +- if (!scribble) { +- err = -ENOMEM; ++ err = alloc_scratch_buffer(conf, per_cpu_ptr(conf->percpu, cpu)); ++ if (err) { ++ pr_err("%s: failed memory allocation for cpu%ld\n", ++ __func__, cpu); + break; + } +- per_cpu_ptr(conf->percpu, cpu)->scribble = scribble; + } +-#ifdef CONFIG_HOTPLUG_CPU +- conf->cpu_notify.notifier_call = raid456_cpu_notify; +- conf->cpu_notify.priority = 0; +- if (err == 0) +- err = register_cpu_notifier(&conf->cpu_notify); +-#endif + put_online_cpus(); + + return err; +diff --git a/drivers/power/max17040_battery.c b/drivers/power/max17040_battery.c +index c284143cfcd7..ec8b948eea4d 100644 +--- a/drivers/power/max17040_battery.c ++++ b/drivers/power/max17040_battery.c +@@ -148,7 +148,7 @@ static void max17040_get_online(struct i2c_client *client) + { + struct max17040_chip *chip = i2c_get_clientdata(client); + +- if (chip->pdata->battery_online) ++ if (chip->pdata && chip->pdata->battery_online) + chip->online = chip->pdata->battery_online(); + else + chip->online = 1; +@@ -158,7 +158,8 @@ static void max17040_get_status(struct i2c_client *client) + { + struct max17040_chip *chip = i2c_get_clientdata(client); + +- if (!chip->pdata->charger_online || !chip->pdata->charger_enable) { ++ if (!chip->pdata || !chip->pdata->charger_online ++ || !chip->pdata->charger_enable) { + chip->status = POWER_SUPPLY_STATUS_UNKNOWN; + return; + } +diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c +index b7a034a3259e..3d8f662e4fe9 100644 +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -572,9 +572,7 @@ static void spi_pump_messages(struct kthread_work *work) + ret = master->transfer_one_message(master, master->cur_msg); + if (ret) { + dev_err(&master->dev, +- "failed to transfer one message from queue: %d\n", ret); +- master->cur_msg->status = ret; +- spi_finalize_current_message(master); ++ "failed to transfer one message from queue\n"); + return; + } + } +diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c +index a8458669350f..0cad46751e00 100644 +--- a/drivers/staging/iio/adc/ad799x_core.c ++++ b/drivers/staging/iio/adc/ad799x_core.c +@@ -873,7 +873,8 @@ static int __devinit ad799x_probe(struct i2c_client *client, + return 0; + + error_free_irq: +- free_irq(client->irq, indio_dev); ++ if (client->irq > 0) ++ free_irq(client->irq, indio_dev); + error_cleanup_ring: + ad799x_ring_cleanup(indio_dev); + error_disable_reg: +diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c +index 4a418e44d562..acc0eab58468 100644 +--- a/drivers/tty/n_gsm.c ++++ b/drivers/tty/n_gsm.c +@@ -1091,6 +1091,7 @@ static void gsm_control_modem(struct gsm_mux *gsm, u8 *data, int clen) + { + unsigned int addr = 0; + unsigned int modem = 0; ++ unsigned int brk = 0; + struct gsm_dlci *dlci; + int len = clen; + u8 *dp = data; +@@ -1117,6 +1118,16 @@ static void gsm_control_modem(struct gsm_mux *gsm, u8 *data, int clen) + if (len == 0) + return; + } ++ len--; ++ if (len > 0) { ++ while (gsm_read_ea(&brk, *dp++) == 0) { ++ len--; ++ if (len == 0) ++ return; ++ } ++ modem <<= 7; ++ modem |= (brk & 0x7f); ++ } + tty = tty_port_tty_get(&dlci->port); + gsm_process_modem(tty, dlci, modem, clen); + if (tty) { +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index 904e8341b2c9..84bd4593455e 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -165,6 +165,7 @@ static struct usb_device_id id_table_combined [] = { + { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_NXTCAM_PID) }, ++ { USB_DEVICE(FTDI_VID, FTDI_EV3CON_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_1_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_2_PID) }, +@@ -204,6 +205,8 @@ static struct usb_device_id id_table_combined [] = { + { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, + { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) }, ++ { USB_DEVICE(FTDI_VID, FTDI_TAGSYS_LP101_PID) }, ++ { USB_DEVICE(FTDI_VID, FTDI_TAGSYS_P200X_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_LENZ_LIUSB_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) }, +diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h +index a7019d1e3058..1e2d369df86e 100644 +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -50,6 +50,7 @@ + #define TI_XDS100V2_PID 0xa6d0 + + #define FTDI_NXTCAM_PID 0xABB8 /* NXTCam for Mindstorms NXT */ ++#define FTDI_EV3CON_PID 0xABB9 /* Mindstorms EV3 Console Adapter */ + + /* US Interface Navigator (http://www.usinterface.com/) */ + #define FTDI_USINT_CAT_PID 0xb810 /* Navigator CAT and 2nd PTT lines */ +@@ -363,6 +364,12 @@ + /* Sprog II (Andrew Crosland's SprogII DCC interface) */ + #define FTDI_SPROG_II 0xF0C8 + ++/* ++ * Two of the Tagsys RFID Readers ++ */ ++#define FTDI_TAGSYS_LP101_PID 0xF0E9 /* Tagsys L-P101 RFID*/ ++#define FTDI_TAGSYS_P200X_PID 0xF0EE /* Tagsys Medio P200x RFID*/ ++ + /* an infrared receiver for user access control with IR tags */ + #define FTDI_PIEGROUP_PID 0xF208 /* Product Id */ + +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 9d7e865a518f..abfb45b3940a 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1376,7 +1376,8 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1267, 0xff, 0xff, 0xff) }, + { 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) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1270, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + { 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) }, +diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig +index 685edc872654..144386bab90b 100644 +--- a/drivers/usb/storage/Kconfig ++++ b/drivers/usb/storage/Kconfig +@@ -19,7 +19,9 @@ config USB_STORAGE + + This option depends on 'SCSI' support being enabled, but you + probably also need 'SCSI device support: SCSI disk support' +- (BLK_DEV_SD) for most USB storage devices. ++ (BLK_DEV_SD) for most USB storage devices. Some devices also ++ will require 'Probe all LUNs on each SCSI device' ++ (SCSI_MULTI_LUN). + + To compile this driver as a module, choose M here: the + module will be called usb-storage. +diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c +index 11418da9bc09..3a7fd6f6af4f 100644 +--- a/drivers/usb/storage/scsiglue.c ++++ b/drivers/usb/storage/scsiglue.c +@@ -78,6 +78,8 @@ static const char* host_info(struct Scsi_Host *host) + + static int slave_alloc (struct scsi_device *sdev) + { ++ struct us_data *us = host_to_us(sdev->host); ++ + /* + * Set the INQUIRY transfer length to 36. We don't use any of + * the extra data and many devices choke if asked for more or +@@ -102,6 +104,10 @@ static int slave_alloc (struct scsi_device *sdev) + */ + blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1)); + ++ /* Tell the SCSI layer if we know there is more than one LUN */ ++ if (us->protocol == USB_PR_BULK && us->max_lun > 0) ++ sdev->sdev_bflags |= BLIST_FORCELUN; ++ + return 0; + } + +diff --git a/drivers/usb/storage/unusual_cypress.h b/drivers/usb/storage/unusual_cypress.h +index 65a6a75066a8..82e8ed0324e3 100644 +--- a/drivers/usb/storage/unusual_cypress.h ++++ b/drivers/usb/storage/unusual_cypress.h +@@ -31,7 +31,7 @@ UNUSUAL_DEV( 0x04b4, 0x6831, 0x0000, 0x9999, + "Cypress ISD-300LP", + USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), + +-UNUSUAL_DEV( 0x14cd, 0x6116, 0x0000, 0x0219, ++UNUSUAL_DEV( 0x14cd, 0x6116, 0x0160, 0x0160, + "Super Top", + "USB 2.0 SATA BRIDGE", + USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), +diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h +index 08d69e5fc143..bbe9adb0eb66 100644 +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -1441,6 +1441,13 @@ UNUSUAL_DEV( 0x0f88, 0x042e, 0x0100, 0x0100, + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + ++/* Reported by Moritz Moeller-Herrmann */ ++UNUSUAL_DEV( 0x0fca, 0x8004, 0x0201, 0x0201, ++ "Research In Motion", ++ "BlackBerry Bold 9000", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_MAX_SECTORS_64 ), ++ + /* Reported by Michael Stattmann */ + UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, + "Sony Ericsson", +diff --git a/fs/file.c b/fs/file.c +index ba3f6053025c..d512ca5ea28f 100644 +--- a/fs/file.c ++++ b/fs/file.c +@@ -47,7 +47,7 @@ static void *alloc_fdmem(size_t size) + * vmalloc() if the allocation size will be considered "large" by the VM. + */ + if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) { +- void *data = kmalloc(size, GFP_KERNEL|__GFP_NOWARN); ++ void *data = kmalloc(size, GFP_KERNEL|__GFP_NOWARN|__GFP_NORETRY); + if (data != NULL) + return data; + } +diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c +index aff1c616aedf..43ccfd6150d9 100644 +--- a/fs/lockd/svclock.c ++++ b/fs/lockd/svclock.c +@@ -769,6 +769,7 @@ nlmsvc_grant_blocked(struct nlm_block *block) + struct nlm_file *file = block->b_file; + struct nlm_lock *lock = &block->b_call->a_args.lock; + int error; ++ loff_t fl_start, fl_end; + + dprintk("lockd: grant blocked lock %p\n", block); + +@@ -786,9 +787,16 @@ nlmsvc_grant_blocked(struct nlm_block *block) + } + + /* Try the lock operation again */ ++ /* vfs_lock_file() can mangle fl_start and fl_end, but we need ++ * them unchanged for the GRANT_MSG ++ */ + lock->fl.fl_flags |= FL_SLEEP; ++ fl_start = lock->fl.fl_start; ++ fl_end = lock->fl.fl_end; + error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL); + lock->fl.fl_flags &= ~FL_SLEEP; ++ lock->fl.fl_start = fl_start; ++ lock->fl.fl_end = fl_end; + + switch (error) { + case 0: +diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c +index 192a302d6cfd..8ab8e9390297 100644 +--- a/kernel/irq/irqdesc.c ++++ b/kernel/irq/irqdesc.c +@@ -274,6 +274,7 @@ struct irq_desc *irq_to_desc(unsigned int irq) + { + return (irq < NR_IRQS) ? irq_desc + irq : NULL; + } ++EXPORT_SYMBOL(irq_to_desc); + + static void free_desc(unsigned int irq) + { +diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c +index a470154e0408..955560e25e05 100644 +--- a/kernel/time/jiffies.c ++++ b/kernel/time/jiffies.c +@@ -51,7 +51,13 @@ + * HZ shrinks, so values greater than 8 overflow 32bits when + * HZ=100. + */ ++#if HZ < 34 ++#define JIFFIES_SHIFT 6 ++#elif HZ < 67 ++#define JIFFIES_SHIFT 7 ++#else + #define JIFFIES_SHIFT 8 ++#endif + + static cycle_t jiffies_read(struct clocksource *cs) + { +diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c +index 28667834181e..bd0f1c499e0a 100644 +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -2008,6 +2008,13 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer, + write &= RB_WRITE_MASK; + tail = write - length; + ++ /* ++ * If this is the first commit on the page, then it has the same ++ * timestamp as the page itself. ++ */ ++ if (!tail) ++ delta = 0; ++ + /* See if we shot pass the end of this buffer page */ + if (unlikely(write > BUF_PAGE_SIZE)) + return rb_move_tail(cpu_buffer, length, tail, +diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c +index eace7664c805..e4b7188a0572 100644 +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -907,7 +907,7 @@ static int ieee80211_fragment(struct ieee80211_tx_data *tx, + } + + /* adjust first fragment's length */ +- skb->len = hdrlen + per_fragm; ++ skb_trim(skb, hdrlen + per_fragm); + return 0; + } + +diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c +index 44ddaa542db6..ea243fef9f02 100644 +--- a/scripts/mod/file2alias.c ++++ b/scripts/mod/file2alias.c +@@ -186,8 +186,8 @@ static void do_usb_entry(struct usb_device_id *id, + range_lo < 0x9 ? "[%X-9" : "[%X", + range_lo); + sprintf(alias + strlen(alias), +- range_hi > 0xA ? "a-%X]" : "%X]", +- range_lo); ++ range_hi > 0xA ? "A-%X]" : "%X]", ++ range_hi); + } + } + if (bcdDevice_initial_digits < (sizeof(id->bcdDevice_lo) * 2 - 1)) +diff --git a/virt/kvm/coalesced_mmio.c b/virt/kvm/coalesced_mmio.c +index 88b2fe3ddf42..00d86427af0f 100644 +--- a/virt/kvm/coalesced_mmio.c ++++ b/virt/kvm/coalesced_mmio.c +@@ -154,17 +154,13 @@ int kvm_vm_ioctl_register_coalesced_mmio(struct kvm *kvm, + list_add_tail(&dev->list, &kvm->coalesced_zones); + mutex_unlock(&kvm->slots_lock); + +- return ret; ++ return 0; + + out_free_dev: + mutex_unlock(&kvm->slots_lock); +- + kfree(dev); + +- if (dev == NULL) +- return -ENXIO; +- +- return 0; ++ return ret; + } + + int kvm_vm_ioctl_unregister_coalesced_mmio(struct kvm *kvm, diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.82-83.patch b/patch/kernel/sun8i-default/0001-patch-3.4.82-83.patch new file mode 100644 index 000000000..d2b2f9d7a --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.82-83.patch @@ -0,0 +1,4277 @@ +diff --git a/Makefile b/Makefile +index ee80efa38844..e677b662f8c5 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 82 ++SUBLEVEL = 83 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h +index 0a5e8a512ee2..420b7d20d520 100644 +--- a/arch/arm/include/asm/cacheflush.h ++++ b/arch/arm/include/asm/cacheflush.h +@@ -202,6 +202,7 @@ extern void copy_to_user_page(struct vm_area_struct *, struct page *, + static inline void __flush_icache_all(void) + { + __flush_icache_preferred(); ++ dsb(); + } + + #define flush_cache_all() __cpuc_flush_kern_all() +diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S +index 897486c5d5f4..4d2e4473b931 100644 +--- a/arch/arm/mm/proc-v6.S ++++ b/arch/arm/mm/proc-v6.S +@@ -202,7 +202,6 @@ __v6_setup: + mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache + mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache + mcr p15, 0, r0, c7, c15, 0 @ clean+invalidate cache +- mcr p15, 0, r0, c7, c10, 4 @ drain write buffer + #ifdef CONFIG_MMU + mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs + mcr p15, 0, r0, c2, c0, 2 @ TTB control register +@@ -212,6 +211,8 @@ __v6_setup: + ALT_UP(orr r8, r8, #TTB_FLAGS_UP) + mcr p15, 0, r8, c2, c0, 1 @ load TTB1 + #endif /* CONFIG_MMU */ ++ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer and ++ @ complete invalidations + adr r5, v6_crval + ldmia r5, {r5, r6} + #ifdef CONFIG_CPU_ENDIAN_BE8 +diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S +index c2e2b66f72b5..fb489cc56713 100644 +--- a/arch/arm/mm/proc-v7.S ++++ b/arch/arm/mm/proc-v7.S +@@ -246,7 +246,6 @@ __v7_setup: + + 3: mov r10, #0 + mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate +- dsb + #ifdef CONFIG_MMU + mcr p15, 0, r10, c8, c7, 0 @ invalidate I + D TLBs + v7_ttb_setup r10, r4, r8, r5 @ TTBCR, TTBRx setup +@@ -255,6 +254,7 @@ __v7_setup: + mcr p15, 0, r5, c10, c2, 0 @ write PRRR + mcr p15, 0, r6, c10, c2, 1 @ write NMRR + #endif ++ dsb @ Complete invalidations + #ifndef CONFIG_ARM_THUMBEE + mrc p15, 0, r0, c0, c1, 0 @ read ID_PFR0 for ThumbEE + and r0, r0, #(0xf << 12) @ ThumbEE enabled field +diff --git a/arch/avr32/Makefile b/arch/avr32/Makefile +index 22fb66590dcd..dba48a5d5bb9 100644 +--- a/arch/avr32/Makefile ++++ b/arch/avr32/Makefile +@@ -11,7 +11,7 @@ all: uImage vmlinux.elf + + KBUILD_DEFCONFIG := atstk1002_defconfig + +-KBUILD_CFLAGS += -pipe -fno-builtin -mno-pic ++KBUILD_CFLAGS += -pipe -fno-builtin -mno-pic -D__linux__ + KBUILD_AFLAGS += -mrelax -mno-pic + KBUILD_CFLAGS_MODULE += -mno-relax + LDFLAGS_vmlinux += --relax +diff --git a/arch/avr32/boards/mimc200/fram.c b/arch/avr32/boards/mimc200/fram.c +index 9764a1a1073e..c1466a872b9c 100644 +--- a/arch/avr32/boards/mimc200/fram.c ++++ b/arch/avr32/boards/mimc200/fram.c +@@ -11,6 +11,7 @@ + #define FRAM_VERSION "1.0" + + #include ++#include + #include + #include + #include +diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c +index b3ba5163eae2..9d6a4a4b37fb 100644 +--- a/arch/powerpc/kernel/crash_dump.c ++++ b/arch/powerpc/kernel/crash_dump.c +@@ -108,17 +108,19 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, + size_t csize, unsigned long offset, int userbuf) + { + void *vaddr; ++ phys_addr_t paddr; + + if (!csize) + return 0; + + csize = min_t(size_t, csize, PAGE_SIZE); ++ paddr = pfn << PAGE_SHIFT; + +- if ((min_low_pfn < pfn) && (pfn < max_pfn)) { +- vaddr = __va(pfn << PAGE_SHIFT); ++ if (memblock_is_region_memory(paddr, csize)) { ++ vaddr = __va(paddr); + csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf); + } else { +- vaddr = __ioremap(pfn << PAGE_SHIFT, PAGE_SIZE, 0); ++ vaddr = __ioremap(paddr, PAGE_SIZE, 0); + csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf); + iounmap(vaddr); + } +diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c +index 968f40101883..59a1edd56d46 100644 +--- a/arch/powerpc/kvm/emulate.c ++++ b/arch/powerpc/kvm/emulate.c +@@ -36,6 +36,7 @@ + #define OP_TRAP_64 2 + + #define OP_31_XOP_LWZX 23 ++#define OP_31_XOP_DCBF 86 + #define OP_31_XOP_LBZX 87 + #define OP_31_XOP_STWX 151 + #define OP_31_XOP_STBX 215 +@@ -373,6 +374,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) + kvmppc_set_exit_type(vcpu, EMULATED_MTSPR_EXITS); + break; + ++ case OP_31_XOP_DCBF: + case OP_31_XOP_DCBI: + /* Do nothing. The guest is performing dcbi because + * hardware DMA is not snooped by the dcache, but +diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c +index e00accf9523e..53c973ebc0c8 100644 +--- a/arch/s390/kvm/kvm-s390.c ++++ b/arch/s390/kvm/kvm-s390.c +@@ -525,13 +525,18 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) + if (!kvm_is_ucontrol(vcpu->kvm)) + kvm_s390_deliver_pending_interrupts(vcpu); + ++ VCPU_EVENT(vcpu, 6, "entering sie flags %x", ++ atomic_read(&vcpu->arch.sie_block->cpuflags)); ++ + vcpu->arch.sie_block->icptcode = 0; + local_irq_disable(); + kvm_guest_enter(); + local_irq_enable(); +- VCPU_EVENT(vcpu, 6, "entering sie flags %x", +- atomic_read(&vcpu->arch.sie_block->cpuflags)); + rc = sie64a(vcpu->arch.sie_block, vcpu->run->s.regs.gprs); ++ local_irq_disable(); ++ kvm_guest_exit(); ++ local_irq_enable(); ++ + if (rc) { + if (kvm_is_ucontrol(vcpu->kvm)) { + rc = SIE_INTERCEPT_UCONTROL; +@@ -543,9 +548,6 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) + } + VCPU_EVENT(vcpu, 6, "exit sie icptcode %d", + vcpu->arch.sie_block->icptcode); +- local_irq_disable(); +- kvm_guest_exit(); +- local_irq_enable(); + + memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16); + return rc; +@@ -902,7 +904,7 @@ static int __init kvm_s390_init(void) + } + memcpy(facilities, S390_lowcore.stfle_fac_list, 16); + facilities[0] &= 0xff00fff3f47c0000ULL; +- facilities[1] &= 0x201c000000000000ULL; ++ facilities[1] &= 0x001c000000000000ULL; + return 0; + } + +diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c +index bb8e03407e18..87477a10e1c8 100644 +--- a/arch/x86/kernel/cpu/perf_event.c ++++ b/arch/x86/kernel/cpu/perf_event.c +@@ -1165,6 +1165,9 @@ static void x86_pmu_del(struct perf_event *event, int flags) + for (i = 0; i < cpuc->n_events; i++) { + if (event == cpuc->event_list[i]) { + ++ if (i >= cpuc->n_events - cpuc->n_added) ++ --cpuc->n_added; ++ + if (x86_pmu.put_event_constraints) + x86_pmu.put_event_constraints(cpuc, event); + +diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c +index a7678fa29fe7..95980387eeb5 100644 +--- a/arch/x86/xen/enlighten.c ++++ b/arch/x86/xen/enlighten.c +@@ -1448,6 +1448,10 @@ asmlinkage void __init xen_start_kernel(void) + + /* Make sure ACS will be enabled */ + pci_request_acs(); ++ ++ /* Avoid searching for BIOS MP tables */ ++ x86_init.mpparse.find_smp_config = x86_init_noop; ++ x86_init.mpparse.get_smp_config = x86_init_uint_noop; + } + #ifdef CONFIG_PCI + /* PCI BIOS service won't work from a PV guest. */ +diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c +index 0503c0c493a9..a7f580623e18 100644 +--- a/arch/x86/xen/smp.c ++++ b/arch/x86/xen/smp.c +@@ -576,6 +576,8 @@ static void xen_hvm_cpu_die(unsigned int cpu) + unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu), NULL); + unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu), NULL); + unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), NULL); ++ xen_uninit_lock_cpu(cpu); ++ xen_teardown_timer(cpu); + native_cpu_die(cpu); + } + +diff --git a/block/blk-exec.c b/block/blk-exec.c +index fb2cbd551621..1b5cb66ef854 100644 +--- a/block/blk-exec.c ++++ b/block/blk-exec.c +@@ -49,8 +49,18 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk, + rq_end_io_fn *done) + { + int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK; ++ bool is_pm_resume; + + WARN_ON(irqs_disabled()); ++ ++ rq->rq_disk = bd_disk; ++ rq->end_io = done; ++ /* ++ * need to check this before __blk_run_queue(), because rq can ++ * be freed before that returns. ++ */ ++ is_pm_resume = rq->cmd_type == REQ_TYPE_PM_RESUME; ++ + spin_lock_irq(q->queue_lock); + + if (unlikely(blk_queue_dead(q))) { +@@ -66,7 +76,7 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk, + __elv_add_request(q, rq, where); + __blk_run_queue(q); + /* the queue is stopped so it won't be run */ +- if (rq->cmd_type == REQ_TYPE_PM_RESUME) ++ if (is_pm_resume) + q->request_fn(q); + spin_unlock_irq(q->queue_lock); + } +diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c +index 1d02b7b5ade0..c653cc2d85c4 100644 +--- a/drivers/acpi/processor_throttling.c ++++ b/drivers/acpi/processor_throttling.c +@@ -59,6 +59,12 @@ struct throttling_tstate { + int target_state; /* target T-state */ + }; + ++struct acpi_processor_throttling_arg { ++ struct acpi_processor *pr; ++ int target_state; ++ bool force; ++}; ++ + #define THROTTLING_PRECHANGE (1) + #define THROTTLING_POSTCHANGE (2) + +@@ -1062,16 +1068,24 @@ static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr, + return 0; + } + ++static long acpi_processor_throttling_fn(void *data) ++{ ++ struct acpi_processor_throttling_arg *arg = data; ++ struct acpi_processor *pr = arg->pr; ++ ++ return pr->throttling.acpi_processor_set_throttling(pr, ++ arg->target_state, arg->force); ++} ++ + int acpi_processor_set_throttling(struct acpi_processor *pr, + int state, bool force) + { +- cpumask_var_t saved_mask; + int ret = 0; + unsigned int i; + struct acpi_processor *match_pr; + struct acpi_processor_throttling *p_throttling; ++ struct acpi_processor_throttling_arg arg; + struct throttling_tstate t_state; +- cpumask_var_t online_throttling_cpus; + + if (!pr) + return -EINVAL; +@@ -1082,14 +1096,6 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, + if ((state < 0) || (state > (pr->throttling.state_count - 1))) + return -EINVAL; + +- if (!alloc_cpumask_var(&saved_mask, GFP_KERNEL)) +- return -ENOMEM; +- +- if (!alloc_cpumask_var(&online_throttling_cpus, GFP_KERNEL)) { +- free_cpumask_var(saved_mask); +- return -ENOMEM; +- } +- + if (cpu_is_offline(pr->id)) { + /* + * the cpu pointed by pr->id is offline. Unnecessary to change +@@ -1098,17 +1104,15 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, + return -ENODEV; + } + +- cpumask_copy(saved_mask, ¤t->cpus_allowed); + t_state.target_state = state; + p_throttling = &(pr->throttling); +- cpumask_and(online_throttling_cpus, cpu_online_mask, +- p_throttling->shared_cpu_map); ++ + /* + * The throttling notifier will be called for every + * affected cpu in order to get one proper T-state. + * The notifier event is THROTTLING_PRECHANGE. + */ +- for_each_cpu(i, online_throttling_cpus) { ++ for_each_cpu_and(i, cpu_online_mask, p_throttling->shared_cpu_map) { + t_state.cpu = i; + acpi_processor_throttling_notifier(THROTTLING_PRECHANGE, + &t_state); +@@ -1120,21 +1124,18 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, + * it can be called only for the cpu pointed by pr. + */ + if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) { +- /* FIXME: use work_on_cpu() */ +- if (set_cpus_allowed_ptr(current, cpumask_of(pr->id))) { +- /* Can't migrate to the pr->id CPU. Exit */ +- ret = -ENODEV; +- goto exit; +- } +- ret = p_throttling->acpi_processor_set_throttling(pr, +- t_state.target_state, force); ++ arg.pr = pr; ++ arg.target_state = state; ++ arg.force = force; ++ ret = work_on_cpu(pr->id, acpi_processor_throttling_fn, &arg); + } else { + /* + * When the T-state coordination is SW_ALL or HW_ALL, + * it is necessary to set T-state for every affected + * cpus. + */ +- for_each_cpu(i, online_throttling_cpus) { ++ for_each_cpu_and(i, cpu_online_mask, ++ p_throttling->shared_cpu_map) { + match_pr = per_cpu(processors, i); + /* + * If the pointer is invalid, we will report the +@@ -1155,13 +1156,12 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, + "on CPU %d\n", i)); + continue; + } +- t_state.cpu = i; +- /* FIXME: use work_on_cpu() */ +- if (set_cpus_allowed_ptr(current, cpumask_of(i))) +- continue; +- ret = match_pr->throttling. +- acpi_processor_set_throttling( +- match_pr, t_state.target_state, force); ++ ++ arg.pr = match_pr; ++ arg.target_state = state; ++ arg.force = force; ++ ret = work_on_cpu(pr->id, acpi_processor_throttling_fn, ++ &arg); + } + } + /* +@@ -1170,17 +1170,12 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, + * affected cpu to update the T-states. + * The notifier event is THROTTLING_POSTCHANGE + */ +- for_each_cpu(i, online_throttling_cpus) { ++ for_each_cpu_and(i, cpu_online_mask, p_throttling->shared_cpu_map) { + t_state.cpu = i; + acpi_processor_throttling_notifier(THROTTLING_POSTCHANGE, + &t_state); + } +- /* restore the previous state */ +- /* FIXME: use work_on_cpu() */ +- set_cpus_allowed_ptr(current, saved_mask); +-exit: +- free_cpumask_var(online_throttling_cpus); +- free_cpumask_var(saved_mask); ++ + return ret; + } + +diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c +index 6d2c49ba47a9..415448af36bf 100644 +--- a/drivers/acpi/video.c ++++ b/drivers/acpi/video.c +@@ -632,6 +632,7 @@ acpi_video_init_brightness(struct acpi_video_device *device) + union acpi_object *o; + struct acpi_video_device_brightness *br = NULL; + int result = -EINVAL; ++ u32 value; + + if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available " +@@ -662,7 +663,12 @@ acpi_video_init_brightness(struct acpi_video_device *device) + printk(KERN_ERR PREFIX "Invalid data\n"); + continue; + } +- br->levels[count] = (u32) o->integer.value; ++ value = (u32) o->integer.value; ++ /* Skip duplicate entries */ ++ if (count > 2 && br->levels[count - 1] == value) ++ continue; ++ ++ br->levels[count] = value; + + if (br->levels[count] > max_level) + max_level = br->levels[count]; +diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c +index f5c35beadc65..0ba32fe00d13 100644 +--- a/drivers/ata/libata-pmp.c ++++ b/drivers/ata/libata-pmp.c +@@ -447,8 +447,11 @@ static void sata_pmp_quirks(struct ata_port *ap) + * otherwise. Don't try hard to recover it. + */ + ap->pmp_link[ap->nr_pmp_links - 1].flags |= ATA_LFLAG_NO_RETRY; +- } else if (vendor == 0x197b && devid == 0x2352) { +- /* chip found in Thermaltake BlackX Duet, jmicron JMB350? */ ++ } else if (vendor == 0x197b && (devid == 0x2352 || devid == 0x0325)) { ++ /* ++ * 0x2352: found in Thermaltake BlackX Duet, jmicron JMB350? ++ * 0x0325: jmicron JMB394. ++ */ + ata_for_each_link(link, ap, EDGE) { + /* SRST breaks detection and disks get misclassified + * LPM disabled to avoid potential problems +diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c +index 9dfb40b8c2c9..0c4ed89b6aa5 100644 +--- a/drivers/ata/sata_sil.c ++++ b/drivers/ata/sata_sil.c +@@ -157,6 +157,7 @@ static const struct sil_drivelist { + { "ST380011ASL", SIL_QUIRK_MOD15WRITE }, + { "ST3120022ASL", SIL_QUIRK_MOD15WRITE }, + { "ST3160021ASL", SIL_QUIRK_MOD15WRITE }, ++ { "TOSHIBA MK2561GSYN", SIL_QUIRK_MOD15WRITE }, + { "Maxtor 4D060H3", SIL_QUIRK_UDMA5MAX }, + { } + }; +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index 386d40e3cf48..d724da52153b 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -590,8 +590,11 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, + nbd_cmd(&sreq) = NBD_CMD_DISC; + if (!nbd->sock) + return -EINVAL; ++ ++ nbd->disconnect = 1; ++ + nbd_send_req(nbd, &sreq); +- return 0; ++ return 0; + } + + case NBD_CLEAR_SOCK: { +@@ -620,6 +623,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, + nbd->sock = SOCKET_I(inode); + if (max_part > 0) + bdev->bd_invalidated = 1; ++ nbd->disconnect = 0; /* we're connected now */ + return 0; + } else { + fput(file); +@@ -691,6 +695,8 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, + set_capacity(nbd->disk, 0); + if (max_part > 0) + ioctl_by_bdev(bdev, BLKRRPART, 0); ++ if (nbd->disconnect) /* user requested, ignore socket errors */ ++ return 0; + return nbd->harderror; + } + +diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c +index 0ed5df4d3e9f..ae1b0c4cfc5b 100644 +--- a/drivers/block/xen-blkback/blkback.c ++++ b/drivers/block/xen-blkback/blkback.c +@@ -274,6 +274,7 @@ int xen_blkif_schedule(void *arg) + { + struct xen_blkif *blkif = arg; + struct xen_vbd *vbd = &blkif->vbd; ++ int ret; + + xen_blkif_get(blkif); + +@@ -294,8 +295,12 @@ int xen_blkif_schedule(void *arg) + blkif->waiting_reqs = 0; + smp_mb(); /* clear flag *before* checking for work */ + +- if (do_block_io_op(blkif)) ++ ret = do_block_io_op(blkif); ++ if (ret > 0) + blkif->waiting_reqs = 1; ++ if (ret == -EACCES) ++ wait_event_interruptible(blkif->shutdown_wq, ++ kthread_should_stop()); + + if (log_stats && time_after(jiffies, blkif->st_print)) + print_stats(blkif); +@@ -531,6 +536,12 @@ __do_block_io_op(struct xen_blkif *blkif) + rp = blk_rings->common.sring->req_prod; + rmb(); /* Ensure we see queued requests up to 'rp'. */ + ++ if (RING_REQUEST_PROD_OVERFLOW(&blk_rings->common, rp)) { ++ rc = blk_rings->common.rsp_prod_pvt; ++ pr_warn(DRV_PFX "Frontend provided bogus ring requests (%d - %d = %d). Halting ring processing on dev=%04x\n", ++ rp, rc, rp - rc, blkif->vbd.pdevice); ++ return -EACCES; ++ } + while (rc != rp) { + + if (RING_REQUEST_CONS_OVERFLOW(&blk_rings->common, rc)) +diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h +index fc2a486d4a8e..933adc5a2637 100644 +--- a/drivers/block/xen-blkback/common.h ++++ b/drivers/block/xen-blkback/common.h +@@ -216,6 +216,8 @@ struct xen_blkif { + int st_wr_sect; + + wait_queue_head_t waiting_to_free; ++ /* Thread shutdown wait queue. */ ++ wait_queue_head_t shutdown_wq; + }; + + +diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c +index a155254f1338..5a0062f1e15c 100644 +--- a/drivers/block/xen-blkback/xenbus.c ++++ b/drivers/block/xen-blkback/xenbus.c +@@ -118,6 +118,7 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid) + atomic_set(&blkif->drain, 0); + blkif->st_print = jiffies; + init_waitqueue_head(&blkif->waiting_to_free); ++ init_waitqueue_head(&blkif->shutdown_wq); + + return blkif; + } +@@ -178,6 +179,7 @@ static void xen_blkif_disconnect(struct xen_blkif *blkif) + { + if (blkif->xenblkd) { + kthread_stop(blkif->xenblkd); ++ wake_up(&blkif->shutdown_wq); + blkif->xenblkd = NULL; + } + +diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c +index ff18e41f5b22..094a7107301d 100644 +--- a/drivers/connector/cn_proc.c ++++ b/drivers/connector/cn_proc.c +@@ -331,6 +331,12 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg, + if (msg->len != sizeof(*mc_op)) + return; + ++ /* Can only change if privileged. */ ++ if (!capable(CAP_NET_ADMIN)) { ++ err = EPERM; ++ goto out; ++ } ++ + mc_op = (enum proc_cn_mcast_op*)msg->data; + switch (*mc_op) { + case PROC_CN_MCAST_LISTEN: +@@ -343,6 +349,8 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg, + err = EINVAL; + break; + } ++ ++out: + cn_proc_ack(err, msg->seq, msg->ack); + } + +diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c +index 2ed1ac3513f3..28a96141bd20 100644 +--- a/drivers/dma/ste_dma40.c ++++ b/drivers/dma/ste_dma40.c +@@ -1409,6 +1409,7 @@ static void dma_tasklet(unsigned long data) + struct d40_chan *d40c = (struct d40_chan *) data; + struct d40_desc *d40d; + unsigned long flags; ++ bool callback_active; + dma_async_tx_callback callback; + void *callback_param; + +@@ -1432,6 +1433,7 @@ static void dma_tasklet(unsigned long data) + } + + /* Callback to client */ ++ callback_active = !!(d40d->txd.flags & DMA_PREP_INTERRUPT); + callback = d40d->txd.callback; + callback_param = d40d->txd.callback_param; + +@@ -1456,7 +1458,7 @@ static void dma_tasklet(unsigned long data) + + spin_unlock_irqrestore(&d40c->lock, flags); + +- if (callback && (d40d->txd.flags & DMA_PREP_INTERRUPT)) ++ if (callback_active && callback) + callback(callback_param); + + return; +diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c +index 0fe2277d8672..ddb725d79fc8 100644 +--- a/drivers/edac/i7core_edac.c ++++ b/drivers/edac/i7core_edac.c +@@ -1365,14 +1365,19 @@ static int i7core_get_onedevice(struct pci_dev **prev, + * is at addr 8086:2c40, instead of 8086:2c41. So, we need + * to probe for the alternate address in case of failure + */ +- if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_I7_NONCORE && !pdev) ++ if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_I7_NONCORE && !pdev) { ++ pci_dev_get(*prev); /* pci_get_device will put it */ + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT, *prev); ++ } + +- if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE && !pdev) ++ if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE && ++ !pdev) { ++ pci_dev_get(*prev); /* pci_get_device will put it */ + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT, + *prev); ++ } + + if (!pdev) { + if (*prev) { +diff --git a/drivers/hwmon/max1668.c b/drivers/hwmon/max1668.c +index 335b183d7c02..f058886ca892 100644 +--- a/drivers/hwmon/max1668.c ++++ b/drivers/hwmon/max1668.c +@@ -243,7 +243,7 @@ static ssize_t set_temp_min(struct device *dev, + data->temp_min[index] = SENSORS_LIMIT(temp/1000, -128, 127); + if (i2c_smbus_write_byte_data(client, + MAX1668_REG_LIML_WR(index), +- data->temp_max[index])) ++ data->temp_min[index])) + count = -EIO; + mutex_unlock(&data->update_lock); + +diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c +index b74cb796c17c..9147569545e2 100644 +--- a/drivers/md/dm-mpath.c ++++ b/drivers/md/dm-mpath.c +@@ -1541,8 +1541,11 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd, + /* + * Only pass ioctls through if the device sizes match exactly. + */ +- if (!r && ti->len != i_size_read(bdev->bd_inode) >> SECTOR_SHIFT) +- r = scsi_verify_blk_ioctl(NULL, cmd); ++ if (!bdev || ti->len != i_size_read(bdev->bd_inode) >> SECTOR_SHIFT) { ++ int err = scsi_verify_blk_ioctl(NULL, cmd); ++ if (err) ++ r = err; ++ } + + return r ? : __blkdev_driver_ioctl(bdev, mode, cmd, arg); + } +diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c +index 10460fd3ce39..dbcdfbf8aed0 100644 +--- a/drivers/media/video/saa7134/saa7134-alsa.c ++++ b/drivers/media/video/saa7134/saa7134-alsa.c +@@ -172,7 +172,9 @@ static void saa7134_irq_alsa_done(struct saa7134_dev *dev, + dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count, + dev->dmasound.bufsize, dev->dmasound.blocks); + spin_unlock(&dev->slock); ++ snd_pcm_stream_lock(dev->dmasound.substream); + snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN); ++ snd_pcm_stream_unlock(dev->dmasound.substream); + return; + } + +diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c +index 3463b469e657..184be29238aa 100644 +--- a/drivers/net/bonding/bond_3ad.c ++++ b/drivers/net/bonding/bond_3ad.c +@@ -1854,8 +1854,6 @@ void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout) + BOND_AD_INFO(bond).agg_select_timer = timeout; + } + +-static u16 aggregator_identifier; +- + /** + * bond_3ad_initialize - initialize a bond's 802.3ad parameters and structures + * @bond: bonding struct to work on +@@ -1869,7 +1867,7 @@ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution) + if (MAC_ADDRESS_COMPARE(&(BOND_AD_INFO(bond).system.sys_mac_addr), + bond->dev->dev_addr)) { + +- aggregator_identifier = 0; ++ BOND_AD_INFO(bond).aggregator_identifier = 0; + + BOND_AD_INFO(bond).system.sys_priority = 0xFFFF; + BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr); +@@ -1941,7 +1939,7 @@ int bond_3ad_bind_slave(struct slave *slave) + ad_initialize_agg(aggregator); + + aggregator->aggregator_mac_address = *((struct mac_addr *)bond->dev->dev_addr); +- aggregator->aggregator_identifier = (++aggregator_identifier); ++ aggregator->aggregator_identifier = ++BOND_AD_INFO(bond).aggregator_identifier; + aggregator->slave = slave; + aggregator->is_active = 0; + aggregator->num_of_ports = 0; +diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h +index 5ee7e3c45db7..656b2f546780 100644 +--- a/drivers/net/bonding/bond_3ad.h ++++ b/drivers/net/bonding/bond_3ad.h +@@ -253,6 +253,7 @@ struct ad_system { + struct ad_bond_info { + struct ad_system system; /* 802.3ad system structure */ + u32 agg_select_timer; // Timer to select aggregator after all adapter's hand shakes ++ u16 aggregator_identifier; + }; + + struct ad_slave_info { +diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c +index 650286be8da1..558974f466de 100644 +--- a/drivers/net/ethernet/broadcom/tg3.c ++++ b/drivers/net/ethernet/broadcom/tg3.c +@@ -12343,12 +12343,12 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) + + tg3_netif_stop(tp); + ++ tg3_set_mtu(dev, tp, new_mtu); ++ + tg3_full_lock(tp, 1); + + tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); + +- tg3_set_mtu(dev, tp, new_mtu); +- + /* Reset PHY, otherwise the read DMA engine will be in a mode that + * breaks all requests to 256 bytes. + */ +diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c +index ef84a586c176..e3e0ca1e92e2 100644 +--- a/drivers/net/usb/asix.c ++++ b/drivers/net/usb/asix.c +@@ -183,6 +183,17 @@ struct ax88172_int_data { + __le16 res3; + } __packed; + ++struct asix_rx_fixup_info { ++ struct sk_buff *ax_skb; ++ u32 header; ++ u16 size; ++ bool split_head; ++}; ++ ++struct asix_common_private { ++ struct asix_rx_fixup_info rx_fixup_info; ++}; ++ + static int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, + u16 size, void *data) + { +@@ -304,49 +315,89 @@ asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, + } + } + +-static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ++static int asix_rx_fixup_internal(struct usbnet *dev, struct sk_buff *skb, ++ struct asix_rx_fixup_info *rx) + { + int offset = 0; + +- while (offset + sizeof(u32) < skb->len) { +- struct sk_buff *ax_skb; +- u16 size; +- u32 header = get_unaligned_le32(skb->data + offset); +- +- offset += sizeof(u32); +- +- /* get the packet length */ +- size = (u16) (header & 0x7ff); +- if (size != ((~header >> 16) & 0x07ff)) { +- netdev_err(dev->net, "asix_rx_fixup() Bad Header Length\n"); +- return 0; ++ while (offset + sizeof(u16) <= skb->len) { ++ u16 remaining = 0; ++ unsigned char *data; ++ ++ if (!rx->size) { ++ if ((skb->len - offset == sizeof(u16)) || ++ rx->split_head) { ++ if (!rx->split_head) { ++ rx->header = get_unaligned_le16( ++ skb->data + offset); ++ rx->split_head = true; ++ offset += sizeof(u16); ++ break; ++ } else { ++ rx->header |= (get_unaligned_le16( ++ skb->data + offset) ++ << 16); ++ rx->split_head = false; ++ offset += sizeof(u16); ++ } ++ } else { ++ rx->header = get_unaligned_le32(skb->data + ++ offset); ++ offset += sizeof(u32); ++ } ++ ++ /* get the packet length */ ++ rx->size = (u16) (rx->header & 0x7ff); ++ if (rx->size != ((~rx->header >> 16) & 0x7ff)) { ++ netdev_err(dev->net, "asix_rx_fixup() Bad Header Length 0x%x, offset %d\n", ++ rx->header, offset); ++ rx->size = 0; ++ return 0; ++ } ++ rx->ax_skb = netdev_alloc_skb_ip_align(dev->net, ++ rx->size); ++ if (!rx->ax_skb) ++ return 0; + } + +- if ((size > dev->net->mtu + ETH_HLEN + VLAN_HLEN) || +- (size + offset > skb->len)) { ++ if (rx->size > dev->net->mtu + ETH_HLEN + VLAN_HLEN) { + netdev_err(dev->net, "asix_rx_fixup() Bad RX Length %d\n", +- size); ++ rx->size); ++ kfree_skb(rx->ax_skb); + return 0; + } +- ax_skb = netdev_alloc_skb_ip_align(dev->net, size); +- if (!ax_skb) +- return 0; + +- skb_put(ax_skb, size); +- memcpy(ax_skb->data, skb->data + offset, size); +- usbnet_skb_return(dev, ax_skb); ++ if (rx->size > skb->len - offset) { ++ remaining = rx->size - (skb->len - offset); ++ rx->size = skb->len - offset; ++ } ++ ++ data = skb_put(rx->ax_skb, rx->size); ++ memcpy(data, skb->data + offset, rx->size); ++ if (!remaining) ++ usbnet_skb_return(dev, rx->ax_skb); + +- offset += (size + 1) & 0xfffe; ++ offset += (rx->size + 1) & 0xfffe; ++ rx->size = remaining; + } + + if (skb->len != offset) { +- netdev_err(dev->net, "asix_rx_fixup() Bad SKB Length %d\n", +- skb->len); ++ netdev_err(dev->net, "asix_rx_fixup() Bad SKB Length %d, %d\n", ++ skb->len, offset); + return 0; + } ++ + return 1; + } + ++static int asix_rx_fixup_common(struct usbnet *dev, struct sk_buff *skb) ++{ ++ struct asix_common_private *dp = dev->driver_priv; ++ struct asix_rx_fixup_info *rx = &dp->rx_fixup_info; ++ ++ return asix_rx_fixup_internal(dev, skb, rx); ++} ++ + static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb, + gfp_t flags) + { +@@ -1110,9 +1161,19 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) + dev->rx_urb_size = 2048; + } + ++ dev->driver_priv = kzalloc(sizeof(struct asix_common_private), ++ GFP_KERNEL); ++ if (!dev->driver_priv) ++ return -ENOMEM; ++ + return 0; + } + ++static void ax88772_unbind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ kfree(dev->driver_priv); ++} ++ + static const struct ethtool_ops ax88178_ethtool_ops = { + .get_drvinfo = asix_get_drvinfo, + .get_link = asix_get_link, +@@ -1445,6 +1506,11 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf) + dev->rx_urb_size = 2048; + } + ++ dev->driver_priv = kzalloc(sizeof(struct asix_common_private), ++ GFP_KERNEL); ++ if (!dev->driver_priv) ++ return -ENOMEM; ++ + return 0; + } + +@@ -1491,22 +1557,26 @@ static const struct driver_info hawking_uf200_info = { + static const struct driver_info ax88772_info = { + .description = "ASIX AX88772 USB 2.0 Ethernet", + .bind = ax88772_bind, ++ .unbind = ax88772_unbind, + .status = asix_status, + .link_reset = ax88772_link_reset, + .reset = ax88772_reset, +- .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | FLAG_MULTI_PACKET, +- .rx_fixup = asix_rx_fixup, ++ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | ++ FLAG_MULTI_PACKET, ++ .rx_fixup = asix_rx_fixup_common, + .tx_fixup = asix_tx_fixup, + }; + + static const struct driver_info ax88178_info = { + .description = "ASIX AX88178 USB 2.0 Ethernet", + .bind = ax88178_bind, ++ .unbind = ax88772_unbind, + .status = asix_status, + .link_reset = ax88178_link_reset, + .reset = ax88178_reset, +- .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR, +- .rx_fixup = asix_rx_fixup, ++ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | ++ FLAG_MULTI_PACKET, ++ .rx_fixup = asix_rx_fixup_common, + .tx_fixup = asix_tx_fixup, + }; + +diff --git a/drivers/net/usb/gl620a.c b/drivers/net/usb/gl620a.c +index 38266bdae26b..71e0b9938602 100644 +--- a/drivers/net/usb/gl620a.c ++++ b/drivers/net/usb/gl620a.c +@@ -86,6 +86,10 @@ static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + u32 size; + u32 count; + ++ /* This check is no longer done by usbnet */ ++ if (skb->len < dev->net->hard_header_len) ++ return 0; ++ + header = (struct gl_header *) skb->data; + + // get the packet count of the received skb +diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c +index c434b6ba0337..21a93775271e 100644 +--- a/drivers/net/usb/mcs7830.c ++++ b/drivers/net/usb/mcs7830.c +@@ -601,8 +601,9 @@ static int mcs7830_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + { + u8 status; + +- if (skb->len == 0) { +- dev_err(&dev->udev->dev, "unexpected empty rx frame\n"); ++ /* This check is no longer done by usbnet */ ++ if (skb->len < dev->net->hard_header_len) { ++ dev_err(&dev->udev->dev, "unexpected tiny rx frame\n"); + return 0; + } + +diff --git a/drivers/net/usb/net1080.c b/drivers/net/usb/net1080.c +index 83f965cb69e7..006a14244a32 100644 +--- a/drivers/net/usb/net1080.c ++++ b/drivers/net/usb/net1080.c +@@ -419,6 +419,10 @@ static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + struct nc_trailer *trailer; + u16 hdr_len, packet_len; + ++ /* This check is no longer done by usbnet */ ++ if (skb->len < dev->net->hard_header_len) ++ return 0; ++ + if (!(skb->len & 0x01)) { + #ifdef DEBUG + struct net_device *net = dev->net; +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index 3b6e932890bb..387ececab6e8 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -202,10 +202,10 @@ static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + { + __be16 proto; + +- /* usbnet rx_complete guarantees that skb->len is at least +- * hard_header_len, so we can inspect the dest address without +- * checking skb->len +- */ ++ /* This check is no longer done by usbnet */ ++ if (skb->len < dev->net->hard_header_len) ++ return 0; ++ + switch (skb->data[0] & 0xf0) { + case 0x40: + proto = htons(ETH_P_IP); +diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c +index c8f1b5b3aff3..bf4c0979c484 100644 +--- a/drivers/net/usb/rndis_host.c ++++ b/drivers/net/usb/rndis_host.c +@@ -490,6 +490,10 @@ EXPORT_SYMBOL_GPL(rndis_unbind); + */ + int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + { ++ /* This check is no longer done by usbnet */ ++ if (skb->len < dev->net->hard_header_len) ++ return 0; ++ + /* peripheral may have batched packets to us... */ + while (likely(skb->len)) { + struct rndis_data_hdr *hdr = (void *)skb->data; +diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c +index d89747aa3c4b..5a82fcdd206b 100644 +--- a/drivers/net/usb/smsc75xx.c ++++ b/drivers/net/usb/smsc75xx.c +@@ -1093,6 +1093,10 @@ static void smsc75xx_rx_csum_offload(struct usbnet *dev, struct sk_buff *skb, + + static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + { ++ /* This check is no longer done by usbnet */ ++ if (skb->len < dev->net->hard_header_len) ++ return 0; ++ + while (skb->len > 0) { + u32 rx_cmd_a, rx_cmd_b, align_count, size; + struct sk_buff *ax_skb; +diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c +index 94ae66999f59..13f50713bf7e 100644 +--- a/drivers/net/usb/smsc95xx.c ++++ b/drivers/net/usb/smsc95xx.c +@@ -1041,6 +1041,10 @@ static void smsc95xx_rx_csum_offload(struct sk_buff *skb) + + static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + { ++ /* This check is no longer done by usbnet */ ++ if (skb->len < dev->net->hard_header_len) ++ return 0; ++ + while (skb->len > 0) { + u32 header, align_count; + struct sk_buff *ax_skb; +diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c +index 174aece3b90a..1283de5b31f3 100644 +--- a/drivers/net/usb/usbnet.c ++++ b/drivers/net/usb/usbnet.c +@@ -415,17 +415,19 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) + } + // else network stack removes extra byte if we forced a short packet + +- if (skb->len) { +- /* all data was already cloned from skb inside the driver */ +- if (dev->driver_info->flags & FLAG_MULTI_PACKET) +- dev_kfree_skb_any(skb); +- else +- usbnet_skb_return(dev, skb); ++ /* all data was already cloned from skb inside the driver */ ++ if (dev->driver_info->flags & FLAG_MULTI_PACKET) ++ goto done; ++ ++ if (skb->len < ETH_HLEN) { ++ dev->net->stats.rx_errors++; ++ dev->net->stats.rx_length_errors++; ++ netif_dbg(dev, rx_err, dev->net, "rx length %d\n", skb->len); ++ } else { ++ usbnet_skb_return(dev, skb); + return; + } + +- netif_dbg(dev, rx_err, dev->net, "drop\n"); +- dev->net->stats.rx_errors++; + done: + skb_queue_tail(&dev->done, skb); + } +@@ -447,13 +449,6 @@ static void rx_complete (struct urb *urb) + switch (urb_status) { + /* success */ + case 0: +- if (skb->len < dev->net->hard_header_len) { +- state = rx_cleanup; +- dev->net->stats.rx_errors++; +- dev->net->stats.rx_length_errors++; +- netif_dbg(dev, rx_err, dev->net, +- "rx length %d\n", skb->len); +- } + break; + + /* stalls need manual reset. this is rare ... except that +diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c +index 2067bdff83ab..dd6dce2bb472 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-6000.c ++++ b/drivers/net/wireless/iwlwifi/iwl-6000.c +@@ -459,6 +459,12 @@ const struct iwl_cfg iwl6035_2agn_cfg = { + .ht_params = &iwl6000_ht_params, + }; + ++const struct iwl_cfg iwl6035_2agn_sff_cfg = { ++ .name = "Intel(R) Centrino(R) Ultimate-N 6235 AGN", ++ IWL_DEVICE_6035, ++ .ht_params = &iwl6000_ht_params, ++}; ++ + const struct iwl_cfg iwl1030_bgn_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", + IWL_DEVICE_6030, +diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c +index 2a9a16f901c3..69d2de11c827 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-agn.c ++++ b/drivers/net/wireless/iwlwifi/iwl-agn.c +@@ -680,7 +680,7 @@ int iwl_alive_start(struct iwl_priv *priv) + BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); + if (ret) + return ret; +- } else { ++ } else if (priv->shrd->cfg->bt_params) { + /* + * default is 2-wire BT coexexistence support + */ +diff --git a/drivers/net/wireless/iwlwifi/iwl-cfg.h b/drivers/net/wireless/iwlwifi/iwl-cfg.h +index 82152311d73b..a133e9e01f0b 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-cfg.h ++++ b/drivers/net/wireless/iwlwifi/iwl-cfg.h +@@ -106,6 +106,7 @@ extern const struct iwl_cfg iwl2000_2bgn_cfg; + extern const struct iwl_cfg iwl2000_2bgn_d_cfg; + extern const struct iwl_cfg iwl2030_2bgn_cfg; + extern const struct iwl_cfg iwl6035_2agn_cfg; ++extern const struct iwl_cfg iwl6035_2agn_sff_cfg; + extern const struct iwl_cfg iwl105_bgn_cfg; + extern const struct iwl_cfg iwl105_bgn_d_cfg; + extern const struct iwl_cfg iwl135_bgn_cfg; +diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c +index 46490d3b95b9..75ebb829c327 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-core.c ++++ b/drivers/net/wireless/iwlwifi/iwl-core.c +@@ -801,7 +801,10 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + +- if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) ++ if (!test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) ++ return; ++ ++ if (ctx->vif) + ieee80211_chswitch_done(ctx->vif, is_success); + } + +diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c +index 2bbaebd99ad4..d587bcdda015 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c ++++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c +@@ -227,6 +227,9 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, + const struct fw_img *img; + size_t bufsz; + ++ if (!iwl_is_ready_rf(priv)) ++ return -EAGAIN; ++ + /* default is to dump the entire data segment */ + if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { + priv->dbgfs_sram_offset = 0x800000; +diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c +index c5e339ee918b..1b9047139f65 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-pci.c ++++ b/drivers/net/wireless/iwlwifi/iwl-pci.c +@@ -138,13 +138,16 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { + + /* 6x00 Series */ + {IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_3agn_cfg)}, ++ {IWL_PCI_DEVICE(0x422B, 0x1108, iwl6000_3agn_cfg)}, + {IWL_PCI_DEVICE(0x422B, 0x1121, iwl6000_3agn_cfg)}, ++ {IWL_PCI_DEVICE(0x422B, 0x1128, iwl6000_3agn_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1301, iwl6000i_2agn_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1306, iwl6000i_2abg_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1307, iwl6000i_2bg_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1321, iwl6000i_2agn_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1326, iwl6000i_2abg_cfg)}, + {IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_3agn_cfg)}, ++ {IWL_PCI_DEVICE(0x4238, 0x1118, iwl6000_3agn_cfg)}, + {IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)}, + {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)}, + +@@ -152,12 +155,16 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { + {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6005_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6005_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6005_2bg_cfg)}, ++ {IWL_PCI_DEVICE(0x0082, 0x1308, iwl6005_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6005_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6005_2abg_cfg)}, ++ {IWL_PCI_DEVICE(0x0082, 0x1328, iwl6005_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6005_2agn_cfg)}, ++ {IWL_PCI_DEVICE(0x0085, 0x1318, iwl6005_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0xC020, iwl6005_2agn_sff_cfg)}, + {IWL_PCI_DEVICE(0x0085, 0xC220, iwl6005_2agn_sff_cfg)}, ++ {IWL_PCI_DEVICE(0x0085, 0xC228, iwl6005_2agn_sff_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x4820, iwl6005_2agn_d_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1304, iwl6005_2agn_mow1_cfg)},/* low 5GHz active */ + {IWL_PCI_DEVICE(0x0082, 0x1305, iwl6005_2agn_mow2_cfg)},/* high 5GHz active */ +@@ -239,8 +246,11 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { + + /* 6x35 Series */ + {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)}, ++ {IWL_PCI_DEVICE(0x088E, 0x406A, iwl6035_2agn_sff_cfg)}, + {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, ++ {IWL_PCI_DEVICE(0x088F, 0x426A, iwl6035_2agn_sff_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, ++ {IWL_PCI_DEVICE(0x088E, 0x446A, iwl6035_2agn_sff_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x4860, iwl6035_2agn_cfg)}, + + /* 105 Series */ +diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +index 3b844b79b14b..9ae2b49270cd 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h ++++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +@@ -209,6 +209,15 @@ struct iwl_queue { + #define TFD_TX_CMD_SLOTS 256 + #define TFD_CMD_SLOTS 32 + ++/* ++ * The FH will write back to the first TB only, so we need ++ * to copy some data into the buffer regardless of whether ++ * it should be mapped or not. This indicates how much to ++ * copy, even for HCMDs it must be big enough to fit the ++ * DRAM scratch from the TX cmd, at least 16 bytes. ++ */ ++#define IWL_HCMD_MIN_COPY_SIZE 16 ++ + struct iwl_tx_queue { + struct iwl_queue q; + struct iwl_tfd *tfds; +@@ -352,7 +361,7 @@ int iwl_queue_space(const struct iwl_queue *q); + ******************************************************/ + int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, + char **buf, bool display); +-int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display); ++int iwl_dump_fh(struct iwl_trans *trans, char **buf); + void iwl_dump_csr(struct iwl_trans *trans); + + /***************************************************** +diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +index aa7aea168138..7bcaeaf4d42e 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c ++++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +@@ -315,6 +315,14 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority) + rxb->page_dma = dma_map_page(trans->dev, page, 0, + PAGE_SIZE << hw_params(trans).rx_page_order, + DMA_FROM_DEVICE); ++ if (dma_mapping_error(trans->dev, rxb->page_dma)) { ++ rxb->page = NULL; ++ spin_lock_irqsave(&rxq->lock, flags); ++ list_add(&rxb->list, &rxq->rx_used); ++ spin_unlock_irqrestore(&rxq->lock, flags); ++ __free_pages(page, hw_params(trans).rx_page_order); ++ return; ++ } + /* dma address must be no more than 36 bits */ + BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); + /* and also 256 byte aligned! */ +@@ -450,8 +458,19 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, + dma_map_page(trans->dev, rxb->page, 0, + PAGE_SIZE << hw_params(trans).rx_page_order, + DMA_FROM_DEVICE); +- list_add_tail(&rxb->list, &rxq->rx_free); +- rxq->free_count++; ++ if (dma_mapping_error(trans->dev, rxb->page_dma)) { ++ /* ++ * free the page(s) as well to not break ++ * the invariant that the items on the used ++ * list have no page(s) ++ */ ++ __free_pages(rxb->page, hw_params(trans).rx_page_order); ++ rxb->page = NULL; ++ list_add_tail(&rxb->list, &rxq->rx_used); ++ } else { ++ list_add_tail(&rxb->list, &rxq->rx_free); ++ rxq->free_count++; ++ } + } else + list_add_tail(&rxb->list, &rxq->rx_used); + spin_unlock_irqrestore(&rxq->lock, flags); +@@ -695,7 +714,7 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) + + iwl_dump_nic_error_log(trans); + iwl_dump_csr(trans); +- iwl_dump_fh(trans, NULL, false); ++ iwl_dump_fh(trans, NULL); + iwl_dump_nic_event_log(trans, false, NULL, false); + + iwl_op_mode_nic_error(trans->op_mode); +@@ -1264,12 +1283,20 @@ static irqreturn_t iwl_isr(int irq, void *data) + * back-to-back ISRs and sporadic interrupts from our NIC. + * If we have something to service, the tasklet will re-enable ints. + * If we *don't* have something, we'll re-enable before leaving here. */ +- inta_mask = iwl_read32(trans, CSR_INT_MASK); /* just for debug */ ++ inta_mask = iwl_read32(trans, CSR_INT_MASK); + iwl_write32(trans, CSR_INT_MASK, 0x00000000); + + /* Discover which interrupts are active/pending */ + inta = iwl_read32(trans, CSR_INT); + ++ if (inta & (~inta_mask)) { ++ IWL_DEBUG_ISR(trans, ++ "We got a masked interrupt (0x%08x)...Ack and ignore\n", ++ inta & (~inta_mask)); ++ iwl_write32(trans, CSR_INT, inta & (~inta_mask)); ++ inta &= inta_mask; ++ } ++ + /* Ignore interrupt if there's nothing in NIC to service. + * This may be due to IRQ shared with another device, + * or due to sporadic interrupts thrown from our NIC. */ +@@ -1353,7 +1380,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) + * If we have something to service, the tasklet will re-enable ints. + * If we *don't* have something, we'll re-enable before leaving here. + */ +- inta_mask = iwl_read32(trans, CSR_INT_MASK); /* just for debug */ ++ inta_mask = iwl_read32(trans, CSR_INT_MASK); + iwl_write32(trans, CSR_INT_MASK, 0x00000000); + + +diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +index d7964b12ef11..91bad2f23842 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c ++++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +@@ -677,10 +677,12 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) + struct iwl_cmd_meta *out_meta; + dma_addr_t phys_addr; + u32 idx; +- u16 copy_size, cmd_size; ++ u16 copy_size, cmd_size, dma_size; + bool had_nocopy = false; + int i; + u8 *cmd_dest; ++ const u8 *cmddata[IWL_MAX_CMD_TFDS]; ++ u16 cmdlen[IWL_MAX_CMD_TFDS]; + #ifdef CONFIG_IWLWIFI_DEVICE_TRACING + const void *trace_bufs[IWL_MAX_CMD_TFDS + 1] = {}; + int trace_lens[IWL_MAX_CMD_TFDS + 1] = {}; +@@ -699,15 +701,30 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) + BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1); + + for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { ++ cmddata[i] = cmd->data[i]; ++ cmdlen[i] = cmd->len[i]; ++ + if (!cmd->len[i]) + continue; ++ ++ /* need at least IWL_HCMD_MIN_COPY_SIZE copied */ ++ if (copy_size < IWL_HCMD_MIN_COPY_SIZE) { ++ int copy = IWL_HCMD_MIN_COPY_SIZE - copy_size; ++ ++ if (copy > cmdlen[i]) ++ copy = cmdlen[i]; ++ cmdlen[i] -= copy; ++ cmddata[i] += copy; ++ copy_size += copy; ++ } ++ + if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) { + had_nocopy = true; + } else { + /* NOCOPY must not be followed by normal! */ + if (WARN_ON(had_nocopy)) + return -EINVAL; +- copy_size += cmd->len[i]; ++ copy_size += cmdlen[i]; + } + cmd_size += cmd->len[i]; + } +@@ -750,13 +767,30 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) + /* and copy the data that needs to be copied */ + + cmd_dest = out_cmd->payload; ++ copy_size = sizeof(out_cmd->hdr); + for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { +- if (!cmd->len[i]) ++ int copy = 0; ++ ++ if (!cmd->len) + continue; +- if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) +- break; +- memcpy(cmd_dest, cmd->data[i], cmd->len[i]); +- cmd_dest += cmd->len[i]; ++ ++ /* need at least IWL_HCMD_MIN_COPY_SIZE copied */ ++ if (copy_size < IWL_HCMD_MIN_COPY_SIZE) { ++ copy = IWL_HCMD_MIN_COPY_SIZE - copy_size; ++ ++ if (copy > cmd->len[i]) ++ copy = cmd->len[i]; ++ } ++ ++ /* copy everything if not nocopy/dup */ ++ if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) ++ copy = cmd->len[i]; ++ ++ if (copy) { ++ memcpy(cmd_dest, cmd->data[i], copy); ++ cmd_dest += copy; ++ copy_size += copy; ++ } + } + + IWL_DEBUG_HC(trans, "Sending command %s (#%x), seq: 0x%04X, " +@@ -766,7 +800,14 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) + le16_to_cpu(out_cmd->hdr.sequence), cmd_size, + q->write_ptr, idx, trans_pcie->cmd_queue); + +- phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, ++ /* ++ * If the entire command is smaller than IWL_HCMD_MIN_COPY_SIZE, we must ++ * still map at least that many bytes for the hardware to write back to. ++ * We have enough space, so that's not a problem. ++ */ ++ dma_size = max_t(u16, copy_size, IWL_HCMD_MIN_COPY_SIZE); ++ ++ phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, dma_size, + DMA_BIDIRECTIONAL); + if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { + idx = -ENOMEM; +@@ -774,7 +815,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) + } + + dma_unmap_addr_set(out_meta, mapping, phys_addr); +- dma_unmap_len_set(out_meta, len, copy_size); ++ dma_unmap_len_set(out_meta, len, dma_size); + + iwlagn_txq_attach_buf_to_tfd(trans, txq, + phys_addr, copy_size, 1); +@@ -801,10 +842,10 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) + } + + iwlagn_txq_attach_buf_to_tfd(trans, txq, phys_addr, +- cmd->len[i], 0); ++ cmdlen[i], 0); + #ifdef CONFIG_IWLWIFI_DEVICE_TRACING +- trace_bufs[trace_idx] = cmd->data[i]; +- trace_lens[trace_idx] = cmd->len[i]; ++ trace_bufs[trace_idx] = cmddata[i]; ++ trace_lens[trace_idx] = cmdlen[i]; + trace_idx++; + #endif + } +diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +index 8741048eb858..1780d3f06073 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c ++++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +@@ -1768,13 +1768,9 @@ static const char *get_fh_string(int cmd) + } + } + +-int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display) ++int iwl_dump_fh(struct iwl_trans *trans, char **buf) + { + int i; +-#ifdef CONFIG_IWLWIFI_DEBUG +- int pos = 0; +- size_t bufsz = 0; +-#endif + static const u32 fh_tbl[] = { + FH_RSCSR_CHNL0_STTS_WPTR_REG, + FH_RSCSR_CHNL0_RBDCB_BASE_REG, +@@ -1786,29 +1782,34 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display) + FH_TSSR_TX_STATUS_REG, + FH_TSSR_TX_ERROR_REG + }; +-#ifdef CONFIG_IWLWIFI_DEBUG +- if (display) { ++ ++#ifdef CONFIG_IWLWIFI_DEBUGFS ++ if (buf) { ++ int pos = 0; ++ size_t bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40; ++ + bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40; + *buf = kmalloc(bufsz, GFP_KERNEL); + if (!*buf) + return -ENOMEM; + pos += scnprintf(*buf + pos, bufsz - pos, + "FH register values:\n"); +- for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { ++ ++ for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) + pos += scnprintf(*buf + pos, bufsz - pos, + " %34s: 0X%08x\n", + get_fh_string(fh_tbl[i]), + iwl_read_direct32(trans, fh_tbl[i])); +- } ++ + return pos; + } + #endif + IWL_ERR(trans, "FH register values:\n"); +- for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { ++ for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) + IWL_ERR(trans, " %34s: 0X%08x\n", + get_fh_string(fh_tbl[i]), + iwl_read_direct32(trans, fh_tbl[i])); +- } ++ + return 0; + } + +@@ -2152,11 +2153,11 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, + size_t count, loff_t *ppos) + { + struct iwl_trans *trans = file->private_data; +- char *buf; ++ char *buf = NULL; + int pos = 0; + ssize_t ret = -EFAULT; + +- ret = pos = iwl_dump_fh(trans, &buf, true); ++ ret = pos = iwl_dump_fh(trans, &buf); + if (buf) { + ret = simple_read_from_buffer(user_buf, + count, ppos, buf, pos); +diff --git a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h +index e19a20a8e955..ecd1ac424047 100644 +--- a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h ++++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h +@@ -15,6 +15,8 @@ + #ifndef RTL8187_H + #define RTL8187_H + ++#include ++ + #include "rtl818x.h" + #include "leds.h" + +@@ -139,7 +141,10 @@ struct rtl8187_priv { + u8 aifsn[4]; + u8 rfkill_mask; + struct { +- __le64 buf; ++ union { ++ __le64 buf; ++ u8 dummy1[L1_CACHE_BYTES]; ++ } ____cacheline_aligned; + struct sk_buff_head queue; + } b_tx_status; /* This queue is used by both -b and non-b devices */ + struct mutex io_mutex; +@@ -147,7 +152,8 @@ struct rtl8187_priv { + u8 bits8; + __le16 bits16; + __le32 bits32; +- } *io_dmabuf; ++ u8 dummy2[L1_CACHE_BYTES]; ++ } *io_dmabuf ____cacheline_aligned; + bool rfkill_off; + u16 seqno; + }; +diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c +index 18d9eb3ad7af..b1757930aa64 100644 +--- a/drivers/net/wireless/rtlwifi/base.c ++++ b/drivers/net/wireless/rtlwifi/base.c +@@ -37,6 +37,7 @@ + + #include + #include ++#include + + /* + *NOTICE!!!: This file will be very big, we should +@@ -957,61 +958,51 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) + if (!ieee80211_is_data(fc)) + return false; + ++ ip = (const struct iphdr *)(skb->data + mac_hdr_len + ++ SNAP_SIZE + PROTOC_TYPE_SIZE); ++ ether_type = be16_to_cpup((__be16 *) ++ (skb->data + mac_hdr_len + SNAP_SIZE)); + +- ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len + +- SNAP_SIZE + PROTOC_TYPE_SIZE); +- ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE); +- /* ether_type = ntohs(ether_type); */ +- +- if (ETH_P_IP == ether_type) { +- if (IPPROTO_UDP == ip->protocol) { +- struct udphdr *udp = (struct udphdr *)((u8 *) ip + +- (ip->ihl << 2)); +- if (((((u8 *) udp)[1] == 68) && +- (((u8 *) udp)[3] == 67)) || +- ((((u8 *) udp)[1] == 67) && +- (((u8 *) udp)[3] == 68))) { +- /* +- * 68 : UDP BOOTP client +- * 67 : UDP BOOTP server +- */ +- RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), +- DBG_DMESG, "dhcp %s !!\n", +- is_tx ? "Tx" : "Rx"); +- +- if (is_tx) { +- schedule_work(&rtlpriv-> +- works.lps_leave_work); +- ppsc->last_delaylps_stamp_jiffies = +- jiffies; +- } ++ switch (ether_type) { ++ case ETH_P_IP: { ++ struct udphdr *udp; ++ u16 src; ++ u16 dst; + +- return true; +- } +- } +- } else if (ETH_P_ARP == ether_type) { +- if (is_tx) { +- schedule_work(&rtlpriv->works.lps_leave_work); +- ppsc->last_delaylps_stamp_jiffies = jiffies; +- } ++ if (ip->protocol != IPPROTO_UDP) ++ return false; ++ udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2)); ++ src = be16_to_cpu(udp->source); ++ dst = be16_to_cpu(udp->dest); + +- return true; +- } else if (ETH_P_PAE == ether_type) { ++ /* If this case involves port 68 (UDP BOOTP client) connecting ++ * with port 67 (UDP BOOTP server), then return true so that ++ * the lowest speed is used. ++ */ ++ if (!((src == 68 && dst == 67) || (src == 67 && dst == 68))) ++ return false; ++ ++ RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, ++ "dhcp %s !!\n", is_tx ? "Tx" : "Rx"); ++ break; ++ } ++ case ETH_P_ARP: ++ break; ++ case ETH_P_PAE: + RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, + "802.1X %s EAPOL pkt!!\n", is_tx ? "Tx" : "Rx"); +- +- if (is_tx) { +- schedule_work(&rtlpriv->works.lps_leave_work); +- ppsc->last_delaylps_stamp_jiffies = jiffies; +- } +- +- return true; +- } else if (ETH_P_IPV6 == ether_type) { +- /* IPv6 */ +- return true; ++ break; ++ case ETH_P_IPV6: ++ /* TODO: Is this right? */ ++ return false; ++ default: ++ return false; + } +- +- return false; ++ if (is_tx) { ++ schedule_work(&rtlpriv->works.lps_leave_work); ++ ppsc->last_delaylps_stamp_jiffies = jiffies; ++ } ++ return true; + } + + /********************************************************* +diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c +index 5b9c3b5e8c92..7fe4f91e0e41 100644 +--- a/drivers/net/wireless/rtlwifi/ps.c ++++ b/drivers/net/wireless/rtlwifi/ps.c +@@ -48,7 +48,7 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw) + + /*<2> Enable Adapter */ + if (rtlpriv->cfg->ops->hw_init(hw)) +- return 1; ++ return false; + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + + /*<3> Enable Interrupt */ +diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +index 509f66195f2f..18ddf57fb863 100644 +--- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c ++++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +@@ -902,14 +902,26 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) + bool is92c; + int err; + u8 tmp_u1b; ++ unsigned long flags; + + rtlpci->being_init_adapter = true; ++ ++ /* Since this function can take a very long time (up to 350 ms) ++ * and can be called with irqs disabled, reenable the irqs ++ * to let the other devices continue being serviced. ++ * ++ * It is safe doing so since our own interrupts will only be enabled ++ * in a subsequent step. ++ */ ++ local_save_flags(flags); ++ local_irq_enable(); ++ + rtlpriv->intf_ops->disable_aspm(hw); + rtstatus = _rtl92ce_init_mac(hw); + if (!rtstatus) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n"); + err = 1; +- return err; ++ goto exit; + } + + err = rtl92c_download_fw(hw); +@@ -917,7 +929,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + "Failed to download FW. Init HW without FW now..\n"); + err = 1; +- return err; ++ goto exit; + } + + rtlhal->last_hmeboxnum = 0; +@@ -978,6 +990,8 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n"); + } + rtl92c_dm_init(hw); ++exit: ++ local_irq_restore(flags); + rtlpci->being_init_adapter = false; + return err; + } +diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h +index 38c51ea483af..905fec4cad06 100644 +--- a/drivers/net/wireless/rtlwifi/wifi.h ++++ b/drivers/net/wireless/rtlwifi/wifi.h +@@ -77,11 +77,7 @@ + #define RTL_SLOT_TIME_9 9 + #define RTL_SLOT_TIME_20 20 + +-/*related with tcp/ip. */ +-/*if_ehther.h*/ +-#define ETH_P_PAE 0x888E /*Port Access Entity (IEEE 802.1X) */ +-#define ETH_P_IP 0x0800 /*Internet Protocol packet */ +-#define ETH_P_ARP 0x0806 /*Address Resolution packet */ ++/*related to tcp/ip. */ + #define SNAP_SIZE 6 + #define PROTOC_TYPE_SIZE 2 + +diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c +index d8ffbf84e3df..a3e5cdd1cf56 100644 +--- a/drivers/net/xen-netback/netback.c ++++ b/drivers/net/xen-netback/netback.c +@@ -46,11 +46,25 @@ + #include + #include + ++/* ++ * This is the maximum slots a skb can have. If a guest sends a skb ++ * which exceeds this limit it is considered malicious. ++ */ ++#define MAX_SKB_SLOTS_DEFAULT 20 ++static unsigned int max_skb_slots = MAX_SKB_SLOTS_DEFAULT; ++module_param(max_skb_slots, uint, 0444); ++ ++typedef unsigned int pending_ring_idx_t; ++#define INVALID_PENDING_RING_IDX (~0U) ++ + struct pending_tx_info { +- struct xen_netif_tx_request req; ++ struct xen_netif_tx_request req; /* coalesced tx request */ + struct xenvif *vif; ++ pending_ring_idx_t head; /* head != INVALID_PENDING_RING_IDX ++ * if it is head of one or more tx ++ * reqs ++ */ + }; +-typedef unsigned int pending_ring_idx_t; + + struct netbk_rx_meta { + int id; +@@ -101,7 +115,11 @@ struct xen_netbk { + atomic_t netfront_count; + + struct pending_tx_info pending_tx_info[MAX_PENDING_REQS]; +- struct gnttab_copy tx_copy_ops[MAX_PENDING_REQS]; ++ /* Coalescing tx requests before copying makes number of grant ++ * copy ops greater or equal to number of slots required. In ++ * worst case a tx request consumes 2 gnttab_copy. ++ */ ++ struct gnttab_copy tx_copy_ops[2*MAX_PENDING_REQS]; + + u16 pending_ring[MAX_PENDING_REQS]; + +@@ -117,6 +135,16 @@ struct xen_netbk { + static struct xen_netbk *xen_netbk; + static int xen_netbk_group_nr; + ++/* ++ * If head != INVALID_PENDING_RING_IDX, it means this tx request is head of ++ * one or more merged tx requests, otherwise it is the continuation of ++ * previous tx request. ++ */ ++static inline int pending_tx_is_head(struct xen_netbk *netbk, RING_IDX idx) ++{ ++ return netbk->pending_tx_info[idx].head != INVALID_PENDING_RING_IDX; ++} ++ + void xen_netbk_add_xenvif(struct xenvif *vif) + { + int i; +@@ -249,6 +277,7 @@ static int max_required_rx_slots(struct xenvif *vif) + { + int max = DIV_ROUND_UP(vif->dev->mtu, PAGE_SIZE); + ++ /* XXX FIXME: RX path dependent on MAX_SKB_FRAGS */ + if (vif->can_sg || vif->gso || vif->gso_prefix) + max += MAX_SKB_FRAGS + 1; /* extra_info + frags */ + +@@ -627,6 +656,7 @@ static void xen_netbk_rx_action(struct xen_netbk *netbk) + __skb_queue_tail(&rxq, skb); + + /* Filled the batch queue? */ ++ /* XXX FIXME: RX path dependent on MAX_SKB_FRAGS */ + if (count + MAX_SKB_FRAGS >= XEN_NETIF_RX_RING_SIZE) + break; + } +@@ -870,47 +900,88 @@ static void netbk_fatal_tx_err(struct xenvif *vif) + + static int netbk_count_requests(struct xenvif *vif, + struct xen_netif_tx_request *first, ++ RING_IDX first_idx, + struct xen_netif_tx_request *txp, + int work_to_do) + { + RING_IDX cons = vif->tx.req_cons; +- int frags = 0; ++ int slots = 0; ++ int drop_err = 0; + + if (!(first->flags & XEN_NETTXF_more_data)) + return 0; + + do { +- if (frags >= work_to_do) { +- netdev_err(vif->dev, "Need more frags\n"); ++ if (slots >= work_to_do) { ++ netdev_err(vif->dev, ++ "Asked for %d slots but exceeds this limit\n", ++ work_to_do); + netbk_fatal_tx_err(vif); + return -ENODATA; + } + +- if (unlikely(frags >= MAX_SKB_FRAGS)) { +- netdev_err(vif->dev, "Too many frags\n"); ++ /* This guest is really using too many slots and ++ * considered malicious. ++ */ ++ if (unlikely(slots >= max_skb_slots)) { ++ netdev_err(vif->dev, ++ "Malicious frontend using %d slots, threshold %u\n", ++ slots, max_skb_slots); + netbk_fatal_tx_err(vif); + return -E2BIG; + } + +- memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + frags), ++ /* Xen network protocol had implicit dependency on ++ * MAX_SKB_FRAGS. XEN_NETIF_NR_SLOTS_MIN is set to the ++ * historical MAX_SKB_FRAGS value 18 to honor the same ++ * behavior as before. Any packet using more than 18 ++ * slots but less than max_skb_slots slots is dropped ++ */ ++ if (!drop_err && slots >= XEN_NETIF_NR_SLOTS_MIN) { ++ if (net_ratelimit()) ++ netdev_dbg(vif->dev, ++ "Too many slots (%d) exceeding limit (%d), dropping packet\n", ++ slots, XEN_NETIF_NR_SLOTS_MIN); ++ drop_err = -E2BIG; ++ } ++ ++ memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + slots), + sizeof(*txp)); +- if (txp->size > first->size) { +- netdev_err(vif->dev, "Frag is bigger than frame.\n"); +- netbk_fatal_tx_err(vif); +- return -EIO; ++ ++ /* If the guest submitted a frame >= 64 KiB then ++ * first->size overflowed and following slots will ++ * appear to be larger than the frame. ++ * ++ * This cannot be fatal error as there are buggy ++ * frontends that do this. ++ * ++ * Consume all slots and drop the packet. ++ */ ++ if (!drop_err && txp->size > first->size) { ++ if (net_ratelimit()) ++ netdev_dbg(vif->dev, ++ "Invalid tx request, slot size %u > remaining size %u\n", ++ txp->size, first->size); ++ drop_err = -EIO; + } + + first->size -= txp->size; +- frags++; ++ slots++; + + if (unlikely((txp->offset + txp->size) > PAGE_SIZE)) { +- netdev_err(vif->dev, "txp->offset: %x, size: %u\n", ++ netdev_err(vif->dev, "Cross page boundary, txp->offset: %x, size: %u\n", + txp->offset, txp->size); + netbk_fatal_tx_err(vif); + return -EINVAL; + } + } while ((txp++)->flags & XEN_NETTXF_more_data); +- return frags; ++ ++ if (drop_err) { ++ netbk_tx_err(vif, first, first_idx + slots); ++ return drop_err; ++ } ++ ++ return slots; + } + + static struct page *xen_netbk_alloc_page(struct xen_netbk *netbk, +@@ -934,48 +1005,114 @@ static struct gnttab_copy *xen_netbk_get_requests(struct xen_netbk *netbk, + struct skb_shared_info *shinfo = skb_shinfo(skb); + skb_frag_t *frags = shinfo->frags; + u16 pending_idx = *((u16 *)skb->data); +- int i, start; ++ u16 head_idx = 0; ++ int slot, start; ++ struct page *page; ++ pending_ring_idx_t index, start_idx = 0; ++ uint16_t dst_offset; ++ unsigned int nr_slots; ++ struct pending_tx_info *first = NULL; ++ ++ /* At this point shinfo->nr_frags is in fact the number of ++ * slots, which can be as large as XEN_NETIF_NR_SLOTS_MIN. ++ */ ++ nr_slots = shinfo->nr_frags; + + /* Skip first skb fragment if it is on same page as header fragment. */ + start = (frag_get_pending_idx(&shinfo->frags[0]) == pending_idx); + +- for (i = start; i < shinfo->nr_frags; i++, txp++) { +- struct page *page; +- pending_ring_idx_t index; ++ /* Coalesce tx requests, at this point the packet passed in ++ * should be <= 64K. Any packets larger than 64K have been ++ * handled in netbk_count_requests(). ++ */ ++ for (shinfo->nr_frags = slot = start; slot < nr_slots; ++ shinfo->nr_frags++) { + struct pending_tx_info *pending_tx_info = + netbk->pending_tx_info; + +- index = pending_index(netbk->pending_cons++); +- pending_idx = netbk->pending_ring[index]; +- page = xen_netbk_alloc_page(netbk, pending_idx); ++ page = alloc_page(GFP_KERNEL|__GFP_COLD); + if (!page) + goto err; + +- gop->source.u.ref = txp->gref; +- gop->source.domid = vif->domid; +- gop->source.offset = txp->offset; +- +- gop->dest.u.gmfn = virt_to_mfn(page_address(page)); +- gop->dest.domid = DOMID_SELF; +- gop->dest.offset = txp->offset; +- +- gop->len = txp->size; +- gop->flags = GNTCOPY_source_gref; ++ dst_offset = 0; ++ first = NULL; ++ while (dst_offset < PAGE_SIZE && slot < nr_slots) { ++ gop->flags = GNTCOPY_source_gref; ++ ++ gop->source.u.ref = txp->gref; ++ gop->source.domid = vif->domid; ++ gop->source.offset = txp->offset; ++ ++ gop->dest.domid = DOMID_SELF; ++ ++ gop->dest.offset = dst_offset; ++ gop->dest.u.gmfn = virt_to_mfn(page_address(page)); ++ ++ if (dst_offset + txp->size > PAGE_SIZE) { ++ /* This page can only merge a portion ++ * of tx request. Do not increment any ++ * pointer / counter here. The txp ++ * will be dealt with in future ++ * rounds, eventually hitting the ++ * `else` branch. ++ */ ++ gop->len = PAGE_SIZE - dst_offset; ++ txp->offset += gop->len; ++ txp->size -= gop->len; ++ dst_offset += gop->len; /* quit loop */ ++ } else { ++ /* This tx request can be merged in the page */ ++ gop->len = txp->size; ++ dst_offset += gop->len; ++ ++ index = pending_index(netbk->pending_cons++); ++ ++ pending_idx = netbk->pending_ring[index]; ++ ++ memcpy(&pending_tx_info[pending_idx].req, txp, ++ sizeof(*txp)); ++ xenvif_get(vif); ++ ++ pending_tx_info[pending_idx].vif = vif; ++ ++ /* Poison these fields, corresponding ++ * fields for head tx req will be set ++ * to correct values after the loop. ++ */ ++ netbk->mmap_pages[pending_idx] = (void *)(~0UL); ++ pending_tx_info[pending_idx].head = ++ INVALID_PENDING_RING_IDX; ++ ++ if (!first) { ++ first = &pending_tx_info[pending_idx]; ++ start_idx = index; ++ head_idx = pending_idx; ++ } ++ ++ txp++; ++ slot++; ++ } + +- gop++; ++ gop++; ++ } + +- memcpy(&pending_tx_info[pending_idx].req, txp, sizeof(*txp)); +- xenvif_get(vif); +- pending_tx_info[pending_idx].vif = vif; +- frag_set_pending_idx(&frags[i], pending_idx); ++ first->req.offset = 0; ++ first->req.size = dst_offset; ++ first->head = start_idx; ++ set_page_ext(page, netbk, head_idx); ++ netbk->mmap_pages[head_idx] = page; ++ frag_set_pending_idx(&frags[shinfo->nr_frags], head_idx); + } + ++ BUG_ON(shinfo->nr_frags > MAX_SKB_FRAGS); ++ + return gop; + err: + /* Unwind, freeing all pages and sending error responses. */ +- while (i-- > start) { +- xen_netbk_idx_release(netbk, frag_get_pending_idx(&frags[i]), +- XEN_NETIF_RSP_ERROR); ++ while (shinfo->nr_frags-- > start) { ++ xen_netbk_idx_release(netbk, ++ frag_get_pending_idx(&frags[shinfo->nr_frags]), ++ XEN_NETIF_RSP_ERROR); + } + /* The head too, if necessary. */ + if (start) +@@ -991,8 +1128,10 @@ static int xen_netbk_tx_check_gop(struct xen_netbk *netbk, + struct gnttab_copy *gop = *gopp; + u16 pending_idx = *((u16 *)skb->data); + struct skb_shared_info *shinfo = skb_shinfo(skb); ++ struct pending_tx_info *tx_info; + int nr_frags = shinfo->nr_frags; + int i, err, start; ++ u16 peek; /* peek into next tx request */ + + /* Check status of header. */ + err = gop->status; +@@ -1004,11 +1143,20 @@ static int xen_netbk_tx_check_gop(struct xen_netbk *netbk, + + for (i = start; i < nr_frags; i++) { + int j, newerr; ++ pending_ring_idx_t head; + + pending_idx = frag_get_pending_idx(&shinfo->frags[i]); ++ tx_info = &netbk->pending_tx_info[pending_idx]; ++ head = tx_info->head; + + /* Check error status: if okay then remember grant handle. */ +- newerr = (++gop)->status; ++ do { ++ newerr = (++gop)->status; ++ if (newerr) ++ break; ++ peek = netbk->pending_ring[pending_index(++head)]; ++ } while (!pending_tx_is_head(netbk, peek)); ++ + if (likely(!newerr)) { + /* Had a previous error? Invalidate this fragment. */ + if (unlikely(err)) +@@ -1233,11 +1381,12 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) + struct sk_buff *skb; + int ret; + +- while (((nr_pending_reqs(netbk) + MAX_SKB_FRAGS) < MAX_PENDING_REQS) && ++ while ((nr_pending_reqs(netbk) + XEN_NETIF_NR_SLOTS_MIN ++ < MAX_PENDING_REQS) && + !list_empty(&netbk->net_schedule_list)) { + struct xenvif *vif; + struct xen_netif_tx_request txreq; +- struct xen_netif_tx_request txfrags[MAX_SKB_FRAGS]; ++ struct xen_netif_tx_request txfrags[max_skb_slots]; + struct page *page; + struct xen_netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX-1]; + u16 pending_idx; +@@ -1298,7 +1447,8 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) + continue; + } + +- ret = netbk_count_requests(vif, &txreq, txfrags, work_to_do); ++ ret = netbk_count_requests(vif, &txreq, idx, ++ txfrags, work_to_do); + if (unlikely(ret < 0)) + continue; + +@@ -1325,7 +1475,7 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) + pending_idx = netbk->pending_ring[index]; + + data_len = (txreq.size > PKT_PROT_LEN && +- ret < MAX_SKB_FRAGS) ? ++ ret < XEN_NETIF_NR_SLOTS_MIN) ? + PKT_PROT_LEN : txreq.size; + + skb = alloc_skb(data_len + NET_SKB_PAD + NET_IP_ALIGN, +@@ -1375,6 +1525,7 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) + memcpy(&netbk->pending_tx_info[pending_idx].req, + &txreq, sizeof(txreq)); + netbk->pending_tx_info[pending_idx].vif = vif; ++ netbk->pending_tx_info[pending_idx].head = index; + *((u16 *)skb->data) = pending_idx; + + __skb_put(skb, data_len); +@@ -1505,7 +1656,10 @@ static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx, + { + struct xenvif *vif; + struct pending_tx_info *pending_tx_info; +- pending_ring_idx_t index; ++ pending_ring_idx_t head; ++ u16 peek; /* peek into next tx request */ ++ ++ BUG_ON(netbk->mmap_pages[pending_idx] == (void *)(~0UL)); + + /* Already complete? */ + if (netbk->mmap_pages[pending_idx] == NULL) +@@ -1514,19 +1668,40 @@ static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx, + pending_tx_info = &netbk->pending_tx_info[pending_idx]; + + vif = pending_tx_info->vif; ++ head = pending_tx_info->head; + +- make_tx_response(vif, &pending_tx_info->req, status); ++ BUG_ON(!pending_tx_is_head(netbk, head)); ++ BUG_ON(netbk->pending_ring[pending_index(head)] != pending_idx); + +- index = pending_index(netbk->pending_prod++); +- netbk->pending_ring[index] = pending_idx; ++ do { ++ pending_ring_idx_t index; ++ pending_ring_idx_t idx = pending_index(head); ++ u16 info_idx = netbk->pending_ring[idx]; + +- xenvif_put(vif); ++ pending_tx_info = &netbk->pending_tx_info[info_idx]; ++ make_tx_response(vif, &pending_tx_info->req, status); ++ ++ /* Setting any number other than ++ * INVALID_PENDING_RING_IDX indicates this slot is ++ * starting a new packet / ending a previous packet. ++ */ ++ pending_tx_info->head = 0; ++ ++ index = pending_index(netbk->pending_prod++); ++ netbk->pending_ring[index] = netbk->pending_ring[info_idx]; ++ ++ xenvif_put(vif); ++ ++ peek = netbk->pending_ring[pending_index(++head)]; ++ ++ } while (!pending_tx_is_head(netbk, peek)); + + netbk->mmap_pages[pending_idx]->mapping = 0; + put_page(netbk->mmap_pages[pending_idx]); + netbk->mmap_pages[pending_idx] = NULL; + } + ++ + static void make_tx_response(struct xenvif *vif, + struct xen_netif_tx_request *txp, + s8 st) +@@ -1579,8 +1754,9 @@ static inline int rx_work_todo(struct xen_netbk *netbk) + static inline int tx_work_todo(struct xen_netbk *netbk) + { + +- if (((nr_pending_reqs(netbk) + MAX_SKB_FRAGS) < MAX_PENDING_REQS) && +- !list_empty(&netbk->net_schedule_list)) ++ if ((nr_pending_reqs(netbk) + XEN_NETIF_NR_SLOTS_MIN ++ < MAX_PENDING_REQS) && ++ !list_empty(&netbk->net_schedule_list)) + return 1; + + return 0; +@@ -1663,6 +1839,13 @@ static int __init netback_init(void) + if (!xen_domain()) + return -ENODEV; + ++ if (max_skb_slots < XEN_NETIF_NR_SLOTS_MIN) { ++ printk(KERN_INFO ++ "xen-netback: max_skb_slots too small (%d), bump it to XEN_NETIF_NR_SLOTS_MIN (%d)\n", ++ max_skb_slots, XEN_NETIF_NR_SLOTS_MIN); ++ max_skb_slots = XEN_NETIF_NR_SLOTS_MIN; ++ } ++ + xen_netbk_group_nr = num_online_cpus(); + xen_netbk = vzalloc(sizeof(struct xen_netbk) * xen_netbk_group_nr); + if (!xen_netbk) +diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c +index 90d2d4475cb4..3f71e9ea051a 100644 +--- a/drivers/staging/line6/pcm.c ++++ b/drivers/staging/line6/pcm.c +@@ -378,8 +378,11 @@ static int snd_line6_pcm_free(struct snd_device *device) + */ + static void pcm_disconnect_substream(struct snd_pcm_substream *substream) + { +- if (substream->runtime && snd_pcm_running(substream)) ++ if (substream->runtime && snd_pcm_running(substream)) { ++ snd_pcm_stream_lock_irq(substream); + snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED); ++ snd_pcm_stream_unlock_irq(substream); ++ } + } + + /* +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index 84bd4593455e..907135c0d161 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -920,6 +920,8 @@ static struct usb_device_id id_table_combined [] = { + /* Crucible Devices */ + { USB_DEVICE(FTDI_VID, FTDI_CT_COMET_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_Z3X_PID) }, ++ /* Cressi Devices */ ++ { USB_DEVICE(FTDI_VID, FTDI_CRESSI_PID) }, + { }, /* Optional parameter entry */ + { } /* Terminating entry */ + }; +diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h +index 1e2d369df86e..e599fbfcde5f 100644 +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -1320,3 +1320,9 @@ + * Manufacturer: Smart GSM Team + */ + #define FTDI_Z3X_PID 0x0011 ++ ++/* ++ * Product: Cressi PC Interface ++ * Manufacturer: Cressi ++ */ ++#define FTDI_CRESSI_PID 0x87d0 +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index abfb45b3940a..8b5c8e5d78d8 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1546,7 +1546,8 @@ static const struct usb_device_id option_ids[] = { + /* Cinterion */ + { 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) }, ++ { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8), ++ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, +diff --git a/drivers/xen/events.c b/drivers/xen/events.c +index 33dcad6371f5..9161f06564eb 100644 +--- a/drivers/xen/events.c ++++ b/drivers/xen/events.c +@@ -1422,8 +1422,10 @@ void rebind_evtchn_irq(int evtchn, int irq) + /* Rebind an evtchn so that it gets delivered to a specific cpu */ + static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu) + { ++ struct shared_info *s = HYPERVISOR_shared_info; + struct evtchn_bind_vcpu bind_vcpu; + int evtchn = evtchn_from_irq(irq); ++ int masked; + + if (!VALID_EVTCHN(evtchn)) + return -1; +@@ -1440,6 +1442,12 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu) + bind_vcpu.vcpu = tcpu; + + /* ++ * Mask the event while changing the VCPU binding to prevent ++ * it being delivered on an unexpected VCPU. ++ */ ++ masked = sync_test_and_set_bit(evtchn, s->evtchn_mask); ++ ++ /* + * If this fails, it usually just indicates that we're dealing with a + * virq or IPI channel, which don't actually need to be rebound. Ignore + * it, but don't do the xenlinux-level rebind in that case. +@@ -1447,6 +1455,9 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu) + if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0) + bind_evtchn_to_cpu(evtchn, tcpu); + ++ if (!masked) ++ unmask_evtchn(evtchn); ++ + return 0; + } + +diff --git a/fs/cifs/file.c b/fs/cifs/file.c +index e7ebb5a2ed1c..9ace37521510 100644 +--- a/fs/cifs/file.c ++++ b/fs/cifs/file.c +@@ -2185,7 +2185,7 @@ cifs_iovec_write(struct file *file, const struct iovec *iov, + unsigned long nr_segs, loff_t *poffset) + { + unsigned long nr_pages, i; +- size_t copied, len, cur_len; ++ size_t bytes, copied, len, cur_len; + ssize_t total_written = 0; + loff_t offset; + struct iov_iter it; +@@ -2236,14 +2236,45 @@ cifs_iovec_write(struct file *file, const struct iovec *iov, + + save_len = cur_len; + for (i = 0; i < nr_pages; i++) { +- copied = min_t(const size_t, cur_len, PAGE_SIZE); ++ bytes = min_t(const size_t, cur_len, PAGE_SIZE); + copied = iov_iter_copy_from_user(wdata->pages[i], &it, +- 0, copied); ++ 0, bytes); + cur_len -= copied; + iov_iter_advance(&it, copied); ++ /* ++ * If we didn't copy as much as we expected, then that ++ * may mean we trod into an unmapped area. Stop copying ++ * at that point. On the next pass through the big ++ * loop, we'll likely end up getting a zero-length ++ * write and bailing out of it. ++ */ ++ if (copied < bytes) ++ break; + } + cur_len = save_len - cur_len; + ++ /* ++ * If we have no data to send, then that probably means that ++ * the copy above failed altogether. That's most likely because ++ * the address in the iovec was bogus. Set the rc to -EFAULT, ++ * free anything we allocated and bail out. ++ */ ++ if (!cur_len) { ++ for (i = 0; i < nr_pages; i++) ++ put_page(wdata->pages[i]); ++ kfree(wdata); ++ rc = -EFAULT; ++ break; ++ } ++ ++ /* ++ * i + 1 now represents the number of pages we actually used in ++ * the copy phase above. Bring nr_pages down to that, and free ++ * any pages that we didn't use. ++ */ ++ for ( ; nr_pages > i + 1; nr_pages--) ++ put_page(wdata->pages[nr_pages - 1]); ++ + wdata->sync_mode = WB_SYNC_ALL; + wdata->nr_pages = nr_pages; + wdata->offset = (__u64)offset; +diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c +index a4217f02fab2..6406ac902de9 100644 +--- a/fs/cifs/readdir.c ++++ b/fs/cifs/readdir.c +@@ -96,6 +96,14 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name, + dput(dentry); + } + ++ /* ++ * If we know that the inode will need to be revalidated immediately, ++ * then don't create a new dentry for it. We'll end up doing an on ++ * the wire call either way and this spares us an invalidation. ++ */ ++ if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL) ++ return NULL; ++ + dentry = d_alloc(parent, name); + if (dentry == NULL) + return NULL; +diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c +index 0961336513d5..103e56ceb38d 100644 +--- a/fs/cifs/transport.c ++++ b/fs/cifs/transport.c +@@ -511,6 +511,13 @@ send_nt_cancel(struct TCP_Server_Info *server, struct smb_hdr *in_buf, + mutex_unlock(&server->srv_mutex); + return rc; + } ++ ++ /* ++ * The response to this call was already factored into the sequence ++ * number when the call went out, so we must adjust it back downward ++ * after signing here. ++ */ ++ --server->sequence_number; + rc = smb_send(server, in_buf, be32_to_cpu(in_buf->smb_buf_length)); + mutex_unlock(&server->srv_mutex); + +diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h +index d918b55f009c..29224866f743 100644 +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -751,6 +751,8 @@ do { \ + if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime)) \ + (einode)->xtime.tv_sec = \ + (signed)le32_to_cpu((raw_inode)->xtime); \ ++ else \ ++ (einode)->xtime.tv_sec = 0; \ + if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime ## _extra)) \ + ext4_decode_extra_time(&(einode)->xtime, \ + raw_inode->xtime ## _extra); \ +diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c +index c883561e9b61..4296a6f800a0 100644 +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -670,6 +670,7 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block, + struct ext4_extent_header *eh; + struct buffer_head *bh; + short int depth, i, ppos = 0, alloc = 0; ++ int ret; + + eh = ext_inode_hdr(inode); + depth = ext_depth(inode); +@@ -699,12 +700,15 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block, + path[ppos].p_ext = NULL; + + bh = sb_getblk(inode->i_sb, path[ppos].p_block); +- if (unlikely(!bh)) ++ if (unlikely(!bh)) { ++ ret = -ENOMEM; + goto err; ++ } + if (!bh_uptodate_or_lock(bh)) { + trace_ext4_ext_load_extent(inode, block, + path[ppos].p_block); +- if (bh_submit_read(bh) < 0) { ++ ret = bh_submit_read(bh); ++ if (ret < 0) { + put_bh(bh); + goto err; + } +@@ -717,13 +721,15 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block, + put_bh(bh); + EXT4_ERROR_INODE(inode, + "ppos %d > depth %d", ppos, depth); ++ ret = -EIO; + goto err; + } + path[ppos].p_bh = bh; + path[ppos].p_hdr = eh; + i--; + +- if (need_to_validate && ext4_ext_check(inode, eh, i)) ++ ret = need_to_validate ? ext4_ext_check(inode, eh, i) : 0; ++ if (ret < 0) + goto err; + } + +@@ -745,7 +751,7 @@ err: + ext4_ext_drop_refs(path); + if (alloc) + kfree(path); +- return ERR_PTR(-EIO); ++ return ERR_PTR(ret); + } + + /* +@@ -900,7 +906,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, + } + bh = sb_getblk(inode->i_sb, newblock); + if (!bh) { +- err = -EIO; ++ err = -ENOMEM; + goto cleanup; + } + lock_buffer(bh); +@@ -972,7 +978,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, + newblock = ablocks[--a]; + bh = sb_getblk(inode->i_sb, newblock); + if (!bh) { +- err = -EIO; ++ err = -ENOMEM; + goto cleanup; + } + lock_buffer(bh); +@@ -1083,11 +1089,8 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, + return err; + + bh = sb_getblk(inode->i_sb, newblock); +- if (!bh) { +- err = -EIO; +- ext4_std_error(inode->i_sb, err); +- return err; +- } ++ if (!bh) ++ return -ENOMEM; + lock_buffer(bh); + + err = ext4_journal_get_create_access(handle, bh); +diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c +index bb6c7d811313..a8d03a4d3f8b 100644 +--- a/fs/ext4/fsync.c ++++ b/fs/ext4/fsync.c +@@ -260,8 +260,7 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync) + if (journal->j_flags & JBD2_BARRIER && + !jbd2_trans_will_send_data_barrier(journal, commit_tid)) + needs_barrier = true; +- jbd2_log_start_commit(journal, commit_tid); +- ret = jbd2_log_wait_commit(journal, commit_tid); ++ ret = jbd2_complete_transaction(journal, commit_tid); + if (needs_barrier) + blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL); + out: +diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c +index 830e1b2bf145..6dc6153dc462 100644 +--- a/fs/ext4/indirect.c ++++ b/fs/ext4/indirect.c +@@ -145,6 +145,7 @@ static Indirect *ext4_get_branch(struct inode *inode, int depth, + struct super_block *sb = inode->i_sb; + Indirect *p = chain; + struct buffer_head *bh; ++ int ret = -EIO; + + *err = 0; + /* i_data is not going away, no lock needed */ +@@ -153,8 +154,10 @@ static Indirect *ext4_get_branch(struct inode *inode, int depth, + goto no_block; + while (--depth) { + bh = sb_getblk(sb, le32_to_cpu(p->key)); +- if (unlikely(!bh)) ++ if (unlikely(!bh)) { ++ ret = -ENOMEM; + goto failure; ++ } + + if (!bh_uptodate_or_lock(bh)) { + if (bh_submit_read(bh) < 0) { +@@ -176,7 +179,7 @@ static Indirect *ext4_get_branch(struct inode *inode, int depth, + return NULL; + + failure: +- *err = -EIO; ++ *err = ret; + no_block: + return p; + } +@@ -470,7 +473,7 @@ static int ext4_alloc_branch(handle_t *handle, struct inode *inode, + */ + bh = sb_getblk(inode->i_sb, new_blocks[n-1]); + if (unlikely(!bh)) { +- err = -EIO; ++ err = -ENOMEM; + goto failed; + } + +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index 98bff01eed6e..25264c4d390f 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -149,8 +149,7 @@ void ext4_evict_inode(struct inode *inode) + journal_t *journal = EXT4_SB(inode->i_sb)->s_journal; + tid_t commit_tid = EXT4_I(inode)->i_datasync_tid; + +- jbd2_log_start_commit(journal, commit_tid); +- jbd2_log_wait_commit(journal, commit_tid); ++ jbd2_complete_transaction(journal, commit_tid); + filemap_write_and_wait(&inode->i_data); + } + truncate_inode_pages(&inode->i_data, 0); +@@ -664,7 +663,7 @@ struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode, + + bh = sb_getblk(inode->i_sb, map.m_pblk); + if (!bh) { +- *errp = -EIO; ++ *errp = -ENOMEM; + return NULL; + } + if (map.m_flags & EXT4_MAP_NEW) { +@@ -2801,9 +2800,9 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset, + if (!(io_end->flag & EXT4_IO_END_UNWRITTEN)) { + ext4_free_io_end(io_end); + out: ++ inode_dio_done(inode); + if (is_async) + aio_complete(iocb, ret, 0); +- inode_dio_done(inode); + return; + } + +@@ -3462,11 +3461,8 @@ static int __ext4_get_inode_loc(struct inode *inode, + iloc->offset = (inode_offset % inodes_per_block) * EXT4_INODE_SIZE(sb); + + bh = sb_getblk(sb, block); +- if (!bh) { +- EXT4_ERROR_INODE_BLOCK(inode, block, +- "unable to read itable block"); +- return -EIO; +- } ++ if (!bh) ++ return -ENOMEM; + if (!buffer_uptodate(bh)) { + lock_buffer(bh); + +diff --git a/fs/ext4/mmp.c b/fs/ext4/mmp.c +index ed6548d89165..444b7016d32d 100644 +--- a/fs/ext4/mmp.c ++++ b/fs/ext4/mmp.c +@@ -41,6 +41,8 @@ static int read_mmp_block(struct super_block *sb, struct buffer_head **bh, + * is not blocked in the elevator. */ + if (!*bh) + *bh = sb_getblk(sb, mmp_block); ++ if (!*bh) ++ return -ENOMEM; + if (*bh) { + get_bh(*bh); + lock_buffer(*bh); +diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c +index dcdeef169a69..6822ad70b55c 100644 +--- a/fs/ext4/page-io.c ++++ b/fs/ext4/page-io.c +@@ -107,14 +107,13 @@ int ext4_end_io_nolock(ext4_io_end_t *io) + inode->i_ino, offset, size, ret); + } + +- if (io->iocb) +- aio_complete(io->iocb, io->result, 0); +- +- if (io->flag & EXT4_IO_END_DIRECT) +- inode_dio_done(inode); + /* Wake up anyone waiting on unwritten extent conversion */ + if (atomic_dec_and_test(&EXT4_I(inode)->i_aiodio_unwritten)) + wake_up_all(ext4_ioend_wq(io->inode)); ++ if (io->flag & EXT4_IO_END_DIRECT) ++ inode_dio_done(inode); ++ if (io->iocb) ++ aio_complete(io->iocb, io->result, 0); + return ret; + } + +diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c +index 86a8c88dc29a..50992c3025c2 100644 +--- a/fs/ext4/resize.c ++++ b/fs/ext4/resize.c +@@ -315,7 +315,7 @@ static struct buffer_head *bclean(handle_t *handle, struct super_block *sb, + + bh = sb_getblk(sb, blk); + if (!bh) +- return ERR_PTR(-EIO); ++ return ERR_PTR(-ENOMEM); + if ((err = ext4_journal_get_write_access(handle, bh))) { + brelse(bh); + bh = ERR_PTR(err); +@@ -377,7 +377,7 @@ static int set_flexbg_block_bitmap(struct super_block *sb, handle_t *handle, + start = ext4_group_first_block_no(sb, group); + group -= flex_gd->groups[0].group; + +- count2 = sb->s_blocksize * 8 - (block - start); ++ count2 = EXT4_BLOCKS_PER_GROUP(sb) - (block - start); + if (count2 > count) + count2 = count; + +@@ -392,7 +392,7 @@ static int set_flexbg_block_bitmap(struct super_block *sb, handle_t *handle, + + bh = sb_getblk(sb, flex_gd->groups[group].block_bitmap); + if (!bh) +- return -EIO; ++ return -ENOMEM; + + err = ext4_journal_get_write_access(handle, bh); + if (err) +@@ -470,7 +470,7 @@ static int setup_new_flex_group_blocks(struct super_block *sb, + + gdb = sb_getblk(sb, block); + if (!gdb) { +- err = -EIO; ++ err = -ENOMEM; + goto out; + } + +@@ -991,7 +991,7 @@ static void update_backups(struct super_block *sb, + + bh = sb_getblk(sb, group * bpg + blk_off); + if (!bh) { +- err = -EIO; ++ err = -ENOMEM; + break; + } + ext4_debug("update metadata backup %#04lx\n", +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 8bbb14c5f774..0b0c03c878e5 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -3370,16 +3370,22 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) + for (i = 0; i < 4; i++) + sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]); + sbi->s_def_hash_version = es->s_def_hash_version; +- i = le32_to_cpu(es->s_flags); +- if (i & EXT2_FLAGS_UNSIGNED_HASH) +- sbi->s_hash_unsigned = 3; +- else if ((i & EXT2_FLAGS_SIGNED_HASH) == 0) { ++ if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) { ++ i = le32_to_cpu(es->s_flags); ++ if (i & EXT2_FLAGS_UNSIGNED_HASH) ++ sbi->s_hash_unsigned = 3; ++ else if ((i & EXT2_FLAGS_SIGNED_HASH) == 0) { + #ifdef __CHAR_UNSIGNED__ +- es->s_flags |= cpu_to_le32(EXT2_FLAGS_UNSIGNED_HASH); +- sbi->s_hash_unsigned = 3; ++ if (!(sb->s_flags & MS_RDONLY)) ++ es->s_flags |= ++ cpu_to_le32(EXT2_FLAGS_UNSIGNED_HASH); ++ sbi->s_hash_unsigned = 3; + #else +- es->s_flags |= cpu_to_le32(EXT2_FLAGS_SIGNED_HASH); ++ if (!(sb->s_flags & MS_RDONLY)) ++ es->s_flags |= ++ cpu_to_le32(EXT2_FLAGS_SIGNED_HASH); + #endif ++ } + } + + /* Handle clustersize */ +diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c +index 01f2cf3409fb..5743e9db8027 100644 +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -840,16 +840,17 @@ inserted: + + new_bh = sb_getblk(sb, block); + if (!new_bh) { ++ error = -ENOMEM; + getblk_failed: + ext4_free_blocks(handle, inode, NULL, block, 1, + EXT4_FREE_BLOCKS_METADATA); +- error = -EIO; + goto cleanup; + } + lock_buffer(new_bh); + error = ext4_journal_get_create_access(handle, new_bh); + if (error) { + unlock_buffer(new_bh); ++ error = -EIO; + goto getblk_failed; + } + memcpy(new_bh->b_data, s->base, new_bh->b_size); +diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c +index 373b25145e01..f31c1365a013 100644 +--- a/fs/fuse/dir.c ++++ b/fs/fuse/dir.c +@@ -1103,6 +1103,8 @@ static int parse_dirfile(char *buf, size_t nbytes, struct file *file, + return -EIO; + if (reclen > nbytes) + break; ++ if (memchr(dirent->name, '/', dirent->namelen) != NULL) ++ return -EIO; + + over = filldir(dstbuf, dirent->name, dirent->namelen, + file->f_pos, dirent->ino, dirent->type); +@@ -1346,6 +1348,7 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, + { + struct inode *inode = entry->d_inode; + struct fuse_conn *fc = get_fuse_conn(inode); ++ struct fuse_inode *fi = get_fuse_inode(inode); + struct fuse_req *req; + struct fuse_setattr_in inarg; + struct fuse_attr_out outarg; +@@ -1376,8 +1379,10 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, + if (IS_ERR(req)) + return PTR_ERR(req); + +- if (is_truncate) ++ if (is_truncate) { + fuse_set_nowrite(inode); ++ set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); ++ } + + memset(&inarg, 0, sizeof(inarg)); + memset(&outarg, 0, sizeof(outarg)); +@@ -1439,12 +1444,14 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, + invalidate_inode_pages2(inode->i_mapping); + } + ++ clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); + return 0; + + error: + if (is_truncate) + fuse_release_nowrite(inode); + ++ clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); + return err; + } + +diff --git a/fs/fuse/file.c b/fs/fuse/file.c +index df25454eadf1..e4f1f1ace347 100644 +--- a/fs/fuse/file.c ++++ b/fs/fuse/file.c +@@ -515,7 +515,8 @@ static void fuse_read_update_size(struct inode *inode, loff_t size, + struct fuse_inode *fi = get_fuse_inode(inode); + + spin_lock(&fc->lock); +- if (attr_ver == fi->attr_version && size < inode->i_size) { ++ if (attr_ver == fi->attr_version && size < inode->i_size && ++ !test_bit(FUSE_I_SIZE_UNSTABLE, &fi->state)) { + fi->attr_version = ++fc->attr_version; + i_size_write(inode, size); + } +@@ -877,12 +878,16 @@ static ssize_t fuse_perform_write(struct file *file, + { + struct inode *inode = mapping->host; + struct fuse_conn *fc = get_fuse_conn(inode); ++ struct fuse_inode *fi = get_fuse_inode(inode); + int err = 0; + ssize_t res = 0; + + if (is_bad_inode(inode)) + return -EIO; + ++ if (inode->i_size < pos + iov_iter_count(ii)) ++ set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); ++ + do { + struct fuse_req *req; + ssize_t count; +@@ -917,6 +922,7 @@ static ssize_t fuse_perform_write(struct file *file, + if (res > 0) + fuse_write_update_size(inode, pos); + ++ clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); + fuse_invalidate_attr(inode); + + return res > 0 ? res : err; +diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h +index d1819269aab0..81b96c58569c 100644 +--- a/fs/fuse/fuse_i.h ++++ b/fs/fuse/fuse_i.h +@@ -103,6 +103,15 @@ struct fuse_inode { + + /** List of writepage requestst (pending or sent) */ + struct list_head writepages; ++ ++ /** Miscellaneous bits describing inode state */ ++ unsigned long state; ++}; ++ ++/** FUSE inode state bits */ ++enum { ++ /** An operation changing file size is in progress */ ++ FUSE_I_SIZE_UNSTABLE, + }; + + struct fuse_conn; +diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c +index a59cf5e673d7..a5c8b343a156 100644 +--- a/fs/fuse/inode.c ++++ b/fs/fuse/inode.c +@@ -92,6 +92,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) + fi->attr_version = 0; + fi->writectr = 0; + fi->orig_ino = 0; ++ fi->state = 0; + INIT_LIST_HEAD(&fi->write_files); + INIT_LIST_HEAD(&fi->queued_writes); + INIT_LIST_HEAD(&fi->writepages); +@@ -199,7 +200,8 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, + loff_t oldsize; + + spin_lock(&fc->lock); +- if (attr_version != 0 && fi->attr_version > attr_version) { ++ if ((attr_version != 0 && fi->attr_version > attr_version) || ++ test_bit(FUSE_I_SIZE_UNSTABLE, &fi->state)) { + spin_unlock(&fc->lock); + return; + } +diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c +index e5bfb1150cf5..f6974688e89f 100644 +--- a/fs/jbd2/journal.c ++++ b/fs/jbd2/journal.c +@@ -662,6 +662,37 @@ int jbd2_log_wait_commit(journal_t *journal, tid_t tid) + } + + /* ++ * When this function returns the transaction corresponding to tid ++ * will be completed. If the transaction has currently running, start ++ * committing that transaction before waiting for it to complete. If ++ * the transaction id is stale, it is by definition already completed, ++ * so just return SUCCESS. ++ */ ++int jbd2_complete_transaction(journal_t *journal, tid_t tid) ++{ ++ int need_to_wait = 1; ++ ++ read_lock(&journal->j_state_lock); ++ if (journal->j_running_transaction && ++ journal->j_running_transaction->t_tid == tid) { ++ if (journal->j_commit_request != tid) { ++ /* transaction not yet started, so request it */ ++ read_unlock(&journal->j_state_lock); ++ jbd2_log_start_commit(journal, tid); ++ goto wait_commit; ++ } ++ } else if (!(journal->j_committing_transaction && ++ journal->j_committing_transaction->t_tid == tid)) ++ need_to_wait = 0; ++ read_unlock(&journal->j_state_lock); ++ if (!need_to_wait) ++ return 0; ++wait_commit: ++ return jbd2_log_wait_commit(journal, tid); ++} ++EXPORT_SYMBOL(jbd2_complete_transaction); ++ ++/* + * Log buffer allocation routines: + */ + +diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c +index aeed93a6bde0..9560fd7f5c7a 100644 +--- a/fs/ncpfs/dir.c ++++ b/fs/ncpfs/dir.c +@@ -1033,15 +1033,6 @@ static int ncp_rmdir(struct inode *dir, struct dentry *dentry) + DPRINTK("ncp_rmdir: removing %s/%s\n", + dentry->d_parent->d_name.name, dentry->d_name.name); + +- /* +- * fail with EBUSY if there are still references to this +- * directory. +- */ +- dentry_unhash(dentry); +- error = -EBUSY; +- if (!d_unhashed(dentry)) +- goto out; +- + len = sizeof(__name); + error = ncp_io2vol(server, __name, &len, dentry->d_name.name, + dentry->d_name.len, !ncp_preserve_case(dir)); +diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c +index 3e7b2a0dc0c8..f45b83f38b1a 100644 +--- a/fs/nilfs2/page.c ++++ b/fs/nilfs2/page.c +@@ -94,6 +94,7 @@ void nilfs_forget_buffer(struct buffer_head *bh) + clear_buffer_nilfs_volatile(bh); + clear_buffer_nilfs_checked(bh); + clear_buffer_nilfs_redirected(bh); ++ clear_buffer_async_write(bh); + clear_buffer_dirty(bh); + if (nilfs_page_buffers_clean(page)) + __nilfs_clear_page_dirty(page); +@@ -390,6 +391,7 @@ void nilfs_clear_dirty_pages(struct address_space *mapping) + bh = head = page_buffers(page); + do { + lock_buffer(bh); ++ clear_buffer_async_write(bh); + clear_buffer_dirty(bh); + clear_buffer_nilfs_volatile(bh); + clear_buffer_nilfs_checked(bh); +diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c +index d4ca8925f017..e0a5a181fa46 100644 +--- a/fs/nilfs2/segment.c ++++ b/fs/nilfs2/segment.c +@@ -662,7 +662,7 @@ static size_t nilfs_lookup_dirty_data_buffers(struct inode *inode, + + bh = head = page_buffers(page); + do { +- if (!buffer_dirty(bh)) ++ if (!buffer_dirty(bh) || buffer_async_write(bh)) + continue; + get_bh(bh); + list_add_tail(&bh->b_assoc_buffers, listp); +@@ -696,7 +696,8 @@ static void nilfs_lookup_dirty_node_buffers(struct inode *inode, + for (i = 0; i < pagevec_count(&pvec); i++) { + bh = head = page_buffers(pvec.pages[i]); + do { +- if (buffer_dirty(bh)) { ++ if (buffer_dirty(bh) && ++ !buffer_async_write(bh)) { + get_bh(bh); + list_add_tail(&bh->b_assoc_buffers, + listp); +@@ -1578,6 +1579,7 @@ static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci) + + list_for_each_entry(bh, &segbuf->sb_segsum_buffers, + b_assoc_buffers) { ++ set_buffer_async_write(bh); + if (bh->b_page != bd_page) { + if (bd_page) { + lock_page(bd_page); +@@ -1591,6 +1593,7 @@ static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci) + + list_for_each_entry(bh, &segbuf->sb_payload_buffers, + b_assoc_buffers) { ++ set_buffer_async_write(bh); + if (bh == segbuf->sb_super_root) { + if (bh->b_page != bd_page) { + lock_page(bd_page); +@@ -1676,6 +1679,7 @@ static void nilfs_abort_logs(struct list_head *logs, int err) + list_for_each_entry(segbuf, logs, sb_list) { + list_for_each_entry(bh, &segbuf->sb_segsum_buffers, + b_assoc_buffers) { ++ clear_buffer_async_write(bh); + if (bh->b_page != bd_page) { + if (bd_page) + end_page_writeback(bd_page); +@@ -1685,6 +1689,7 @@ static void nilfs_abort_logs(struct list_head *logs, int err) + + list_for_each_entry(bh, &segbuf->sb_payload_buffers, + b_assoc_buffers) { ++ clear_buffer_async_write(bh); + if (bh == segbuf->sb_super_root) { + if (bh->b_page != bd_page) { + end_page_writeback(bd_page); +@@ -1754,6 +1759,7 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) + b_assoc_buffers) { + set_buffer_uptodate(bh); + clear_buffer_dirty(bh); ++ clear_buffer_async_write(bh); + if (bh->b_page != bd_page) { + if (bd_page) + end_page_writeback(bd_page); +@@ -1775,6 +1781,7 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) + b_assoc_buffers) { + set_buffer_uptodate(bh); + clear_buffer_dirty(bh); ++ clear_buffer_async_write(bh); + clear_buffer_delay(bh); + clear_buffer_nilfs_volatile(bh); + clear_buffer_nilfs_redirected(bh); +diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c +index d69a1d1d7e15..8b3068771dab 100644 +--- a/fs/quota/dquot.c ++++ b/fs/quota/dquot.c +@@ -580,9 +580,17 @@ int dquot_scan_active(struct super_block *sb, + dqstats_inc(DQST_LOOKUPS); + dqput(old_dquot); + old_dquot = dquot; +- ret = fn(dquot, priv); +- if (ret < 0) +- goto out; ++ /* ++ * ->release_dquot() can be racing with us. Our reference ++ * protects us from new calls to it so just wait for any ++ * outstanding call and recheck the DQ_ACTIVE_B after that. ++ */ ++ wait_on_dquot(dquot); ++ if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { ++ ret = fn(dquot, priv); ++ if (ret < 0) ++ goto out; ++ } + spin_lock(&dq_list_lock); + /* We are safe to continue now because our dquot could not + * be moved out of the inuse list while we hold the reference */ +diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c +index c542c73cfa3c..f9c90b552452 100644 +--- a/fs/ubifs/orphan.c ++++ b/fs/ubifs/orphan.c +@@ -130,13 +130,14 @@ void ubifs_delete_orphan(struct ubifs_info *c, ino_t inum) + else if (inum > o->inum) + p = p->rb_right; + else { +- if (o->dnext) { ++ if (o->del) { + spin_unlock(&c->orphan_lock); + dbg_gen("deleted twice ino %lu", + (unsigned long)inum); + return; + } + if (o->cnext) { ++ o->del = 1; + o->dnext = c->orph_dnext; + c->orph_dnext = o; + spin_unlock(&c->orphan_lock); +@@ -447,6 +448,7 @@ static void erase_deleted(struct ubifs_info *c) + orphan = dnext; + dnext = orphan->dnext; + ubifs_assert(!orphan->new); ++ ubifs_assert(orphan->del); + rb_erase(&orphan->rb, &c->orph_tree); + list_del(&orphan->list); + c->tot_orphans -= 1; +@@ -536,6 +538,7 @@ static int insert_dead_orphan(struct ubifs_info *c, ino_t inum) + rb_link_node(&orphan->rb, parent, p); + rb_insert_color(&orphan->rb, &c->orph_tree); + list_add_tail(&orphan->list, &c->orph_list); ++ orphan->del = 1; + orphan->dnext = c->orph_dnext; + c->orph_dnext = orphan; + dbg_mnt("ino %lu, new %d, tot %d", (unsigned long)inum, +diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h +index 4971cb23b6c8..3f962617e29b 100644 +--- a/fs/ubifs/ubifs.h ++++ b/fs/ubifs/ubifs.h +@@ -905,6 +905,7 @@ struct ubifs_budget_req { + * @dnext: next orphan to delete + * @inum: inode number + * @new: %1 => added since the last commit, otherwise %0 ++ * @del: %1 => delete pending, otherwise %0 + */ + struct ubifs_orphan { + struct rb_node rb; +@@ -914,6 +915,7 @@ struct ubifs_orphan { + struct ubifs_orphan *dnext; + ino_t inum; + int new; ++ unsigned del:1; + }; + + /** +diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h +index 5a85b3415c1b..be71efc36bba 100644 +--- a/include/linux/cgroup.h ++++ b/include/linux/cgroup.h +@@ -32,7 +32,6 @@ extern int cgroup_lock_is_held(void); + extern bool cgroup_lock_live_group(struct cgroup *cgrp); + extern void cgroup_unlock(void); + extern void cgroup_fork(struct task_struct *p); +-extern void cgroup_fork_callbacks(struct task_struct *p); + extern void cgroup_post_fork(struct task_struct *p); + extern void cgroup_exit(struct task_struct *p, int run_callbacks); + extern int cgroupstats_build(struct cgroupstats *stats, +@@ -514,16 +513,54 @@ static inline struct cgroup_subsys_state *cgroup_subsys_state( + return cgrp->subsys[subsys_id]; + } + +-/* +- * function to get the cgroup_subsys_state which allows for extra +- * rcu_dereference_check() conditions, such as locks used during the +- * cgroup_subsys::attach() methods. ++/** ++ * task_css_set_check - obtain a task's css_set with extra access conditions ++ * @task: the task to obtain css_set for ++ * @__c: extra condition expression to be passed to rcu_dereference_check() ++ * ++ * A task's css_set is RCU protected, initialized and exited while holding ++ * task_lock(), and can only be modified while holding both cgroup_mutex ++ * and task_lock() while the task is alive. This macro verifies that the ++ * caller is inside proper critical section and returns @task's css_set. ++ * ++ * The caller can also specify additional allowed conditions via @__c, such ++ * as locks used during the cgroup_subsys::attach() methods. ++ */ ++#define task_css_set_check(task, __c) \ ++ rcu_dereference_check((task)->cgroups, \ ++ lockdep_is_held(&(task)->alloc_lock) || \ ++ cgroup_lock_is_held() || (__c)) ++ ++/** ++ * task_subsys_state_check - obtain css for (task, subsys) w/ extra access conds ++ * @task: the target task ++ * @subsys_id: the target subsystem ID ++ * @__c: extra condition expression to be passed to rcu_dereference_check() ++ * ++ * Return the cgroup_subsys_state for the (@task, @subsys_id) pair. The ++ * synchronization rules are the same as task_css_set_check(). + */ + #define task_subsys_state_check(task, subsys_id, __c) \ +- rcu_dereference_check(task->cgroups->subsys[subsys_id], \ +- lockdep_is_held(&task->alloc_lock) || \ +- cgroup_lock_is_held() || (__c)) ++ task_css_set_check((task), (__c))->subsys[(subsys_id)] + ++/** ++ * task_css_set - obtain a task's css_set ++ * @task: the task to obtain css_set for ++ * ++ * See task_css_set_check(). ++ */ ++static inline struct css_set *task_css_set(struct task_struct *task) ++{ ++ return task_css_set_check(task, false); ++} ++ ++/** ++ * task_subsys_state - obtain css for (task, subsys) ++ * @task: the target task ++ * @subsys_id: the target subsystem ID ++ * ++ * See task_subsys_state_check(). ++ */ + static inline struct cgroup_subsys_state * + task_subsys_state(struct task_struct *task, int subsys_id) + { +diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h +index dd6444f67ed1..2ffbf9938a31 100644 +--- a/include/linux/jbd2.h ++++ b/include/linux/jbd2.h +@@ -1178,6 +1178,7 @@ int __jbd2_log_start_commit(journal_t *journal, tid_t tid); + int jbd2_journal_start_commit(journal_t *journal, tid_t *tid); + int jbd2_journal_force_commit_nested(journal_t *journal); + int jbd2_log_wait_commit(journal_t *journal, tid_t tid); ++int jbd2_complete_transaction(journal_t *journal, tid_t tid); + int jbd2_log_do_checkpoint(journal_t *journal); + int jbd2_trans_will_send_data_barrier(journal_t *journal, tid_t tid); + +diff --git a/include/linux/nbd.h b/include/linux/nbd.h +index d146ca10c0f5..e6fe17431b95 100644 +--- a/include/linux/nbd.h ++++ b/include/linux/nbd.h +@@ -68,6 +68,7 @@ struct nbd_device { + u64 bytesize; + pid_t pid; /* pid of nbd-client, if attached */ + int xmit_timeout; ++ int disconnect; /* a disconnect has been requested by user */ + }; + + #endif +diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h +index 42b919c36da1..3a7b87e1fd89 100644 +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -2159,6 +2159,8 @@ extern int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, + extern struct sk_buff *skb_segment(struct sk_buff *skb, + netdev_features_t features); + ++unsigned int skb_gso_transport_seglen(const struct sk_buff *skb); ++ + static inline void *skb_header_pointer(const struct sk_buff *skb, int offset, + int len, void *buffer) + { +@@ -2580,5 +2582,22 @@ static inline bool skb_is_recycleable(const struct sk_buff *skb, int skb_size) + + return true; + } ++ ++/** ++ * skb_gso_network_seglen - Return length of individual segments of a gso packet ++ * ++ * @skb: GSO skb ++ * ++ * skb_gso_network_seglen is used to determine the real size of the ++ * individual segments, including Layer3 (IP, IPv6) and L4 headers (TCP/UDP). ++ * ++ * The MAC/L2 header is not accounted for. ++ */ ++static inline unsigned int skb_gso_network_seglen(const struct sk_buff *skb) ++{ ++ unsigned int hdr_len = skb_transport_header(skb) - ++ skb_network_header(skb); ++ return hdr_len + skb_gso_transport_seglen(skb); ++} + #endif /* __KERNEL__ */ + #endif /* _LINUX_SKBUFF_H */ +diff --git a/include/xen/interface/io/netif.h b/include/xen/interface/io/netif.h +index cb94668f6e9f..a36c87a6623d 100644 +--- a/include/xen/interface/io/netif.h ++++ b/include/xen/interface/io/netif.h +@@ -13,6 +13,24 @@ + #include "../grant_table.h" + + /* ++ * Older implementation of Xen network frontend / backend has an ++ * implicit dependency on the MAX_SKB_FRAGS as the maximum number of ++ * ring slots a skb can use. Netfront / netback may not work as ++ * expected when frontend and backend have different MAX_SKB_FRAGS. ++ * ++ * A better approach is to add mechanism for netfront / netback to ++ * negotiate this value. However we cannot fix all possible ++ * frontends, so we need to define a value which states the minimum ++ * slots backend must support. ++ * ++ * The minimum value derives from older Linux kernel's MAX_SKB_FRAGS ++ * (18), which is proved to work with most frontends. Any new backend ++ * which doesn't negotiate with frontend should expect frontend to ++ * send a valid packet using slots up to this value. ++ */ ++#define XEN_NETIF_NR_SLOTS_MIN 18 ++ ++/* + * Notifications after enqueuing any type of message should be conditional on + * the appropriate req_event or rsp_event field in the shared ring. + * If the client sends notification for rx requests then it should specify +diff --git a/include/xen/interface/io/ring.h b/include/xen/interface/io/ring.h +index 75271b9a8f61..7d28aff605c7 100644 +--- a/include/xen/interface/io/ring.h ++++ b/include/xen/interface/io/ring.h +@@ -188,6 +188,11 @@ struct __name##_back_ring { \ + #define RING_REQUEST_CONS_OVERFLOW(_r, _cons) \ + (((_cons) - (_r)->rsp_prod_pvt) >= RING_SIZE(_r)) + ++/* Ill-behaved frontend determination: Can there be this many requests? */ ++#define RING_REQUEST_PROD_OVERFLOW(_r, _prod) \ ++ (((_prod) - (_r)->rsp_prod_pvt) > RING_SIZE(_r)) ++ ++ + #define RING_PUSH_REQUESTS(_r) do { \ + wmb(); /* back sees requests /before/ updated producer index */ \ + (_r)->sring->req_prod = (_r)->req_prod_pvt; \ +diff --git a/kernel/cgroup.c b/kernel/cgroup.c +index 519c252f0fc8..7c8f4f7d0c71 100644 +--- a/kernel/cgroup.c ++++ b/kernel/cgroup.c +@@ -4497,41 +4497,19 @@ void cgroup_fork(struct task_struct *child) + } + + /** +- * cgroup_fork_callbacks - run fork callbacks +- * @child: the new task +- * +- * Called on a new task very soon before adding it to the +- * tasklist. No need to take any locks since no-one can +- * be operating on this task. +- */ +-void cgroup_fork_callbacks(struct task_struct *child) +-{ +- if (need_forkexit_callback) { +- int i; +- /* +- * forkexit callbacks are only supported for builtin +- * subsystems, and the builtin section of the subsys array is +- * immutable, so we don't need to lock the subsys array here. +- */ +- for (i = 0; i < CGROUP_BUILTIN_SUBSYS_COUNT; i++) { +- struct cgroup_subsys *ss = subsys[i]; +- if (ss->fork) +- ss->fork(child); +- } +- } +-} +- +-/** + * cgroup_post_fork - called on a new task after adding it to the task list + * @child: the task in question + * +- * Adds the task to the list running through its css_set if necessary. +- * Has to be after the task is visible on the task list in case we race +- * with the first call to cgroup_iter_start() - to guarantee that the +- * new task ends up on its list. ++ * Adds the task to the list running through its css_set if necessary and ++ * call the subsystem fork() callbacks. Has to be after the task is ++ * visible on the task list in case we race with the first call to ++ * cgroup_iter_start() - to guarantee that the new task ends up on its ++ * list. + */ + void cgroup_post_fork(struct task_struct *child) + { ++ int i; ++ + /* + * use_task_css_set_links is set to 1 before we walk the tasklist + * under the tasklist_lock and we read it here after we added the child +@@ -4551,7 +4529,21 @@ void cgroup_post_fork(struct task_struct *child) + task_unlock(child); + write_unlock(&css_set_lock); + } ++ ++ /* ++ * Call ss->fork(). This must happen after @child is linked on ++ * css_set; otherwise, @child might change state between ->fork() ++ * and addition to css_set. ++ */ ++ if (need_forkexit_callback) { ++ for (i = 0; i < CGROUP_BUILTIN_SUBSYS_COUNT; i++) { ++ struct cgroup_subsys *ss = subsys[i]; ++ if (ss->fork) ++ ss->fork(child); ++ } ++ } + } ++ + /** + * cgroup_exit - detach cgroup from exiting task + * @tsk: pointer to task_struct of exiting process +diff --git a/kernel/cgroup_freezer.c b/kernel/cgroup_freezer.c +index f86e93920b62..a902e2adc40a 100644 +--- a/kernel/cgroup_freezer.c ++++ b/kernel/cgroup_freezer.c +@@ -186,23 +186,15 @@ static void freezer_fork(struct task_struct *task) + { + struct freezer *freezer; + +- /* +- * No lock is needed, since the task isn't on tasklist yet, +- * so it can't be moved to another cgroup, which means the +- * freezer won't be removed and will be valid during this +- * function call. Nevertheless, apply RCU read-side critical +- * section to suppress RCU lockdep false positives. +- */ + rcu_read_lock(); + freezer = task_freezer(task); +- rcu_read_unlock(); + + /* + * The root cgroup is non-freezable, so we can skip the + * following check. + */ + if (!freezer->css.cgroup->parent) +- return; ++ goto out; + + spin_lock_irq(&freezer->lock); + BUG_ON(freezer->state == CGROUP_FROZEN); +@@ -210,7 +202,10 @@ static void freezer_fork(struct task_struct *task) + /* Locking avoids race with FREEZING -> THAWED transitions. */ + if (freezer->state == CGROUP_FREEZING) + freeze_task(task); ++ + spin_unlock_irq(&freezer->lock); ++out: ++ rcu_read_unlock(); + } + + /* +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 8e82398c2843..eba82e2d34e9 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -7149,14 +7149,14 @@ static void perf_pmu_rotate_stop(struct pmu *pmu) + static void __perf_event_exit_context(void *__info) + { + struct perf_event_context *ctx = __info; +- struct perf_event *event, *tmp; ++ struct perf_event *event; + + perf_pmu_rotate_stop(ctx->pmu); + +- list_for_each_entry_safe(event, tmp, &ctx->pinned_groups, group_entry) +- __perf_remove_from_context(event); +- list_for_each_entry_safe(event, tmp, &ctx->flexible_groups, group_entry) ++ rcu_read_lock(); ++ list_for_each_entry_rcu(event, &ctx->event_list, event_entry) + __perf_remove_from_context(event); ++ rcu_read_unlock(); + } + + static void perf_event_exit_cpu_context(int cpu) +@@ -7180,11 +7180,11 @@ static void perf_event_exit_cpu(int cpu) + { + struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu); + ++ perf_event_exit_cpu_context(cpu); ++ + mutex_lock(&swhash->hlist_mutex); + swevent_hlist_release(swhash); + mutex_unlock(&swhash->hlist_mutex); +- +- perf_event_exit_cpu_context(cpu); + } + #else + static inline void perf_event_exit_cpu(int cpu) { } +diff --git a/kernel/fork.c b/kernel/fork.c +index 81633337aee1..afac42b8889c 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -1124,7 +1124,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, + { + int retval; + struct task_struct *p; +- int cgroup_callbacks_done = 0; + + if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS)) + return ERR_PTR(-EINVAL); +@@ -1383,12 +1382,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, + p->group_leader = p; + INIT_LIST_HEAD(&p->thread_group); + +- /* Now that the task is set up, run cgroup callbacks if +- * necessary. We need to run them before the task is visible +- * on the tasklist. */ +- cgroup_fork_callbacks(p); +- cgroup_callbacks_done = 1; +- + /* Need tasklist lock for parent etc handling! */ + write_lock_irq(&tasklist_lock); + +@@ -1493,7 +1486,7 @@ bad_fork_cleanup_cgroup: + #endif + if (clone_flags & CLONE_THREAD) + threadgroup_change_end(current); +- cgroup_exit(p, cgroup_callbacks_done); ++ cgroup_exit(p, 0); + delayacct_tsk_free(p); + module_put(task_thread_info(p)->exec_domain->module); + bad_fork_cleanup_count: +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index 575d092fa746..13ea688f2761 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -1469,12 +1469,19 @@ static void destroy_worker(struct worker *worker) + if (worker->flags & WORKER_IDLE) + gcwq->nr_idle--; + ++ /* ++ * Once WORKER_DIE is set, the kworker may destroy itself at any ++ * point. Pin to ensure the task stays until we're done with it. ++ */ ++ get_task_struct(worker->task); ++ + list_del_init(&worker->entry); + worker->flags |= WORKER_DIE; + + spin_unlock_irq(&gcwq->lock); + + kthread_stop(worker->task); ++ put_task_struct(worker->task); + kfree(worker); + + spin_lock_irq(&gcwq->lock); +diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c +index 9ad7d1ef6ac1..09d87b709179 100644 +--- a/mm/memory_hotplug.c ++++ b/mm/memory_hotplug.c +@@ -515,19 +515,20 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages) + + zone->present_pages += onlined_pages; + zone->zone_pgdat->node_present_pages += onlined_pages; +- if (need_zonelists_rebuild) +- build_all_zonelists(zone); +- else +- zone_pcp_update(zone); ++ if (onlined_pages) { ++ node_set_state(zone_to_nid(zone), N_HIGH_MEMORY); ++ if (need_zonelists_rebuild) ++ build_all_zonelists(zone); ++ else ++ zone_pcp_update(zone); ++ } + + mutex_unlock(&zonelists_mutex); + + init_per_zone_wmark_min(); + +- if (onlined_pages) { ++ if (onlined_pages) + kswapd_run(zone_to_nid(zone)); +- node_set_state(zone_to_nid(zone), N_HIGH_MEMORY); +- } + + vm_total_pages = nr_free_pagecache_pages(); + + +diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c +index 8e3aa4dc5bec..d8f031a762ae 100644 +--- a/net/ceph/osd_client.c ++++ b/net/ceph/osd_client.c +@@ -1721,6 +1721,8 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc, + dout("osdc_start_request failed map, " + " will retry %lld\n", req->r_tid); + rc = 0; ++ } else { ++ __unregister_request(osdc, req); + } + goto out_unlock; + } +diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c +index c0c21b1ce1ec..6af54f2d0da0 100644 +--- a/net/core/fib_rules.c ++++ b/net/core/fib_rules.c +@@ -718,6 +718,13 @@ static int fib_rules_event(struct notifier_block *this, unsigned long event, + attach_rules(&ops->rules_list, dev); + break; + ++ case NETDEV_CHANGENAME: ++ list_for_each_entry(ops, &net->rules_ops, list) { ++ detach_rules(&ops->rules_list, dev); ++ attach_rules(&ops->rules_list, dev); ++ } ++ break; ++ + case NETDEV_UNREGISTER: + list_for_each_entry(ops, &net->rules_ops, list) + detach_rules(&ops->rules_list, dev); +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index e99aedd9c496..7a597d4feaec 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -45,6 +45,8 @@ + #include + #include + #include ++#include ++#include + #include + #ifdef CONFIG_NET_CLS_ACT + #include +@@ -3281,3 +3283,26 @@ void __skb_warn_lro_forwarding(const struct sk_buff *skb) + " while LRO is enabled\n", skb->dev->name); + } + EXPORT_SYMBOL(__skb_warn_lro_forwarding); ++ ++/** ++ * skb_gso_transport_seglen - Return length of individual segments of a gso packet ++ * ++ * @skb: GSO skb ++ * ++ * skb_gso_transport_seglen is used to determine the real size of the ++ * individual segments, including Layer4 headers (TCP/UDP). ++ * ++ * The MAC/L2 or network (IP, IPv6) headers are not accounted for. ++ */ ++unsigned int skb_gso_transport_seglen(const struct sk_buff *skb) ++{ ++ const struct skb_shared_info *shinfo = skb_shinfo(skb); ++ unsigned int hdr_len; ++ ++ if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))) ++ hdr_len = tcp_hdrlen(skb); ++ else ++ hdr_len = sizeof(struct udphdr); ++ return hdr_len + shinfo->gso_size; ++} ++EXPORT_SYMBOL_GPL(skb_gso_transport_seglen); +diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c +index 29a07b6c7168..e0d9f02fec11 100644 +--- a/net/ipv4/ip_forward.c ++++ b/net/ipv4/ip_forward.c +@@ -39,6 +39,68 @@ + #include + #include + ++static bool ip_may_fragment(const struct sk_buff *skb) ++{ ++ return unlikely((ip_hdr(skb)->frag_off & htons(IP_DF)) == 0) || ++ !skb->local_df; ++} ++ ++static bool ip_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu) ++{ ++ if (skb->len <= mtu || skb->local_df) ++ return false; ++ ++ if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu) ++ return false; ++ ++ return true; ++} ++ ++static bool ip_gso_exceeds_dst_mtu(const struct sk_buff *skb) ++{ ++ unsigned int mtu; ++ ++ if (skb->local_df || !skb_is_gso(skb)) ++ return false; ++ ++ mtu = dst_mtu(skb_dst(skb)); ++ ++ /* if seglen > mtu, do software segmentation for IP fragmentation on ++ * output. DF bit cannot be set since ip_forward would have sent ++ * icmp error. ++ */ ++ return skb_gso_network_seglen(skb) > mtu; ++} ++ ++/* called if GSO skb needs to be fragmented on forward */ ++static int ip_forward_finish_gso(struct sk_buff *skb) ++{ ++ struct sk_buff *segs; ++ int ret = 0; ++ ++ segs = skb_gso_segment(skb, 0); ++ if (IS_ERR(segs)) { ++ kfree_skb(skb); ++ return -ENOMEM; ++ } ++ ++ consume_skb(skb); ++ ++ do { ++ struct sk_buff *nskb = segs->next; ++ int err; ++ ++ segs->next = NULL; ++ err = dst_output(segs); ++ ++ if (err && ret == 0) ++ ret = err; ++ segs = nskb; ++ } while (segs); ++ ++ return ret; ++} ++ + static int ip_forward_finish(struct sk_buff *skb) + { + struct ip_options * opt = &(IPCB(skb)->opt); +@@ -48,6 +110,9 @@ static int ip_forward_finish(struct sk_buff *skb) + if (unlikely(opt->optlen)) + ip_forward_options(skb); + ++ if (ip_gso_exceeds_dst_mtu(skb)) ++ return ip_forward_finish_gso(skb); ++ + return dst_output(skb); + } + +@@ -87,8 +152,7 @@ int ip_forward(struct sk_buff *skb) + if (opt->is_strictroute && opt->nexthop != rt->rt_gateway) + goto sr_failed; + +- if (unlikely(skb->len > dst_mtu(&rt->dst) && !skb_is_gso(skb) && +- (ip_hdr(skb)->frag_off & htons(IP_DF))) && !skb->local_df) { ++ if (!ip_may_fragment(skb) && ip_exceeds_mtu(skb, dst_mtu(&rt->dst))) { + IP_INC_STATS(dev_net(rt->dst.dev), IPSTATS_MIB_FRAGFAILS); + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, + htonl(dst_mtu(&rt->dst))); +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index 91cd5f1657b7..8cd6854c2cae 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -382,6 +382,17 @@ static inline int ip6_forward_finish(struct sk_buff *skb) + return dst_output(skb); + } + ++static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu) ++{ ++ if (skb->len <= mtu || skb->local_df) ++ return false; ++ ++ if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu) ++ return false; ++ ++ return true; ++} ++ + int ip6_forward(struct sk_buff *skb) + { + struct dst_entry *dst = skb_dst(skb); +@@ -503,7 +514,7 @@ int ip6_forward(struct sk_buff *skb) + if (mtu < IPV6_MIN_MTU) + mtu = IPV6_MIN_MTU; + +- if (skb->len > mtu && !skb_is_gso(skb)) { ++ if (ip6_pkt_too_big(skb, mtu)) { + /* Again, force OUTPUT device used as source address */ + skb->dev = dst->dev; + icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); +diff --git a/net/sctp/socket.c b/net/sctp/socket.c +index e9e50cadd52f..0ed156b537d2 100644 +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -70,6 +70,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -1376,11 +1377,19 @@ SCTP_STATIC int sctp_setsockopt_connectx(struct sock* sk, + /* + * New (hopefully final) interface for the API. + * We use the sctp_getaddrs_old structure so that use-space library +- * can avoid any unnecessary allocations. The only defferent part ++ * can avoid any unnecessary allocations. The only different part + * is that we store the actual length of the address buffer into the +- * addrs_num structure member. That way we can re-use the existing ++ * addrs_num structure member. That way we can re-use the existing + * code. + */ ++#ifdef CONFIG_COMPAT ++struct compat_sctp_getaddrs_old { ++ sctp_assoc_t assoc_id; ++ s32 addr_num; ++ compat_uptr_t addrs; /* struct sockaddr * */ ++}; ++#endif ++ + SCTP_STATIC int sctp_getsockopt_connectx3(struct sock* sk, int len, + char __user *optval, + int __user *optlen) +@@ -1389,16 +1398,30 @@ SCTP_STATIC int sctp_getsockopt_connectx3(struct sock* sk, int len, + sctp_assoc_t assoc_id = 0; + int err = 0; + +- if (len < sizeof(param)) +- return -EINVAL; ++#ifdef CONFIG_COMPAT ++ if (is_compat_task()) { ++ struct compat_sctp_getaddrs_old param32; + +- if (copy_from_user(¶m, optval, sizeof(param))) +- return -EFAULT; ++ if (len < sizeof(param32)) ++ return -EINVAL; ++ if (copy_from_user(¶m32, optval, sizeof(param32))) ++ return -EFAULT; + +- err = __sctp_setsockopt_connectx(sk, +- (struct sockaddr __user *)param.addrs, +- param.addr_num, &assoc_id); ++ param.assoc_id = param32.assoc_id; ++ param.addr_num = param32.addr_num; ++ param.addrs = compat_ptr(param32.addrs); ++ } else ++#endif ++ { ++ if (len < sizeof(param)) ++ return -EINVAL; ++ if (copy_from_user(¶m, optval, sizeof(param))) ++ return -EFAULT; ++ } + ++ err = __sctp_setsockopt_connectx(sk, (struct sockaddr __user *) ++ param.addrs, param.addr_num, ++ &assoc_id); + if (err == 0 || err == -EINPROGRESS) { + if (copy_to_user(optval, &assoc_id, sizeof(assoc_id))) + return -EFAULT; +diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c +index 72d89e129caa..c3930172c06c 100644 +--- a/net/sunrpc/sched.c ++++ b/net/sunrpc/sched.c +@@ -302,13 +302,20 @@ EXPORT_SYMBOL_GPL(__rpc_wait_for_completion_task); + /* + * Make an RPC task runnable. + * +- * Note: If the task is ASYNC, this must be called with +- * the spinlock held to protect the wait queue operation. ++ * Note: If the task is ASYNC, and is being made runnable after sitting on an ++ * rpc_wait_queue, this must be called with the queue spinlock held to protect ++ * the wait queue operation. ++ * Note the ordering of rpc_test_and_set_running() and rpc_clear_queued(), ++ * which is needed to ensure that __rpc_execute() doesn't loop (due to the ++ * lockless RPC_IS_QUEUED() test) before we've had a chance to test ++ * the RPC_TASK_RUNNING flag. + */ + static void rpc_make_runnable(struct rpc_task *task) + { ++ bool need_wakeup = !rpc_test_and_set_running(task); ++ + rpc_clear_queued(task); +- if (rpc_test_and_set_running(task)) ++ if (!need_wakeup) + return; + if (RPC_IS_ASYNC(task)) { + INIT_WORK(&task->u.tk_work, rpc_async_schedule); +diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c +index 31f981d700a3..31275e52c667 100644 +--- a/net/sunrpc/xprtsock.c ++++ b/net/sunrpc/xprtsock.c +@@ -501,6 +501,7 @@ static int xs_nospace(struct rpc_task *task) + struct rpc_rqst *req = task->tk_rqstp; + struct rpc_xprt *xprt = req->rq_xprt; + struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); ++ struct sock *sk = transport->inet; + int ret = -EAGAIN; + + dprintk("RPC: %5u xmit incomplete (%u left of %u)\n", +@@ -518,7 +519,7 @@ static int xs_nospace(struct rpc_task *task) + * window size + */ + set_bit(SOCK_NOSPACE, &transport->sock->flags); +- transport->inet->sk_write_pending++; ++ sk->sk_write_pending++; + /* ...and wait for more buffer space */ + xprt_wait_for_buffer_space(task, xs_nospace_callback); + } +@@ -528,6 +529,9 @@ static int xs_nospace(struct rpc_task *task) + } + + spin_unlock_bh(&xprt->transport_lock); ++ ++ /* Race breaker in case memory is freed before above code is called */ ++ sk->sk_write_space(sk); + return ret; + } + +diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c +index 1249e17b61ff..23e9cba8d4d2 100644 +--- a/security/selinux/ss/policydb.c ++++ b/security/selinux/ss/policydb.c +@@ -3214,10 +3214,10 @@ static int filename_write_helper(void *key, void *data, void *ptr) + if (rc) + return rc; + +- buf[0] = ft->stype; +- buf[1] = ft->ttype; +- buf[2] = ft->tclass; +- buf[3] = otype->otype; ++ buf[0] = cpu_to_le32(ft->stype); ++ buf[1] = cpu_to_le32(ft->ttype); ++ buf[2] = cpu_to_le32(ft->tclass); ++ buf[3] = cpu_to_le32(otype->otype); + + rc = put_entry(buf, sizeof(u32), 4, fp); + if (rc) +diff --git a/sound/arm/pxa2xx-pcm-lib.c b/sound/arm/pxa2xx-pcm-lib.c +index 76e0d5695075..823359ed95e1 100644 +--- a/sound/arm/pxa2xx-pcm-lib.c ++++ b/sound/arm/pxa2xx-pcm-lib.c +@@ -166,7 +166,9 @@ void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id) + } else { + printk(KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n", + rtd->params->name, dma_ch, dcsr); ++ snd_pcm_stream_lock(substream); + snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); ++ snd_pcm_stream_unlock(substream); + } + } + EXPORT_SYMBOL(pxa2xx_pcm_dma_irq); +diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c +index e8de831f98bc..05093bd3c390 100644 +--- a/sound/pci/asihpi/asihpi.c ++++ b/sound/pci/asihpi/asihpi.c +@@ -769,7 +769,10 @@ static void snd_card_asihpi_timer_function(unsigned long data) + s->number); + ds->drained_count++; + if (ds->drained_count > 20) { ++ unsigned long flags; ++ snd_pcm_stream_lock_irqsave(s, flags); + snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); ++ snd_pcm_stream_unlock_irqrestore(s, flags); + continue; + } + } else { +diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c +index 590682f115ef..0c48216a74ba 100644 +--- a/sound/pci/atiixp.c ++++ b/sound/pci/atiixp.c +@@ -688,7 +688,9 @@ static void snd_atiixp_xrun_dma(struct atiixp *chip, struct atiixp_dma *dma) + if (! dma->substream || ! dma->running) + return; + snd_printdd("atiixp: XRUN detected (DMA %d)\n", dma->ops->type); ++ snd_pcm_stream_lock(dma->substream); + snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN); ++ snd_pcm_stream_unlock(dma->substream); + } + + /* +diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c +index 524d35f31232..94d6e9bf245b 100644 +--- a/sound/pci/atiixp_modem.c ++++ b/sound/pci/atiixp_modem.c +@@ -638,7 +638,9 @@ static void snd_atiixp_xrun_dma(struct atiixp_modem *chip, + if (! dma->substream || ! dma->running) + return; + snd_printdd("atiixp-modem: XRUN detected (DMA %d)\n", dma->ops->type); ++ snd_pcm_stream_lock(dma->substream); + snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN); ++ snd_pcm_stream_unlock(dma->substream); + } + + /* +diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c +index 8e92fb88ed09..f0b8d8e38f71 100644 +--- a/sound/soc/codecs/sgtl5000.c ++++ b/sound/soc/codecs/sgtl5000.c +@@ -37,7 +37,7 @@ + static const u16 sgtl5000_regs[SGTL5000_MAX_REG_OFFSET] = { + [SGTL5000_CHIP_CLK_CTRL] = 0x0008, + [SGTL5000_CHIP_I2S_CTRL] = 0x0010, +- [SGTL5000_CHIP_SSS_CTRL] = 0x0008, ++ [SGTL5000_CHIP_SSS_CTRL] = 0x0010, + [SGTL5000_CHIP_DAC_VOL] = 0x3c3c, + [SGTL5000_CHIP_PAD_STRENGTH] = 0x015f, + [SGTL5000_CHIP_ANA_HP_CTRL] = 0x1818, +diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c +index 7db6fa515028..e05da9171ddd 100644 +--- a/sound/soc/codecs/sta32x.c ++++ b/sound/soc/codecs/sta32x.c +@@ -147,42 +147,42 @@ static const unsigned int sta32x_limiter_drc_release_tlv[] = { + 13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0), + }; + +-static const struct soc_enum sta32x_drc_ac_enum = +- SOC_ENUM_SINGLE(STA32X_CONFD, STA32X_CONFD_DRC_SHIFT, +- 2, sta32x_drc_ac); +-static const struct soc_enum sta32x_auto_eq_enum = +- SOC_ENUM_SINGLE(STA32X_AUTO1, STA32X_AUTO1_AMEQ_SHIFT, +- 3, sta32x_auto_eq_mode); +-static const struct soc_enum sta32x_auto_gc_enum = +- SOC_ENUM_SINGLE(STA32X_AUTO1, STA32X_AUTO1_AMGC_SHIFT, +- 4, sta32x_auto_gc_mode); +-static const struct soc_enum sta32x_auto_xo_enum = +- SOC_ENUM_SINGLE(STA32X_AUTO2, STA32X_AUTO2_XO_SHIFT, +- 16, sta32x_auto_xo_mode); +-static const struct soc_enum sta32x_preset_eq_enum = +- SOC_ENUM_SINGLE(STA32X_AUTO3, STA32X_AUTO3_PEQ_SHIFT, +- 32, sta32x_preset_eq_mode); +-static const struct soc_enum sta32x_limiter_ch1_enum = +- SOC_ENUM_SINGLE(STA32X_C1CFG, STA32X_CxCFG_LS_SHIFT, +- 3, sta32x_limiter_select); +-static const struct soc_enum sta32x_limiter_ch2_enum = +- SOC_ENUM_SINGLE(STA32X_C2CFG, STA32X_CxCFG_LS_SHIFT, +- 3, sta32x_limiter_select); +-static const struct soc_enum sta32x_limiter_ch3_enum = +- SOC_ENUM_SINGLE(STA32X_C3CFG, STA32X_CxCFG_LS_SHIFT, +- 3, sta32x_limiter_select); +-static const struct soc_enum sta32x_limiter1_attack_rate_enum = +- SOC_ENUM_SINGLE(STA32X_L1AR, STA32X_LxA_SHIFT, +- 16, sta32x_limiter_attack_rate); +-static const struct soc_enum sta32x_limiter2_attack_rate_enum = +- SOC_ENUM_SINGLE(STA32X_L2AR, STA32X_LxA_SHIFT, +- 16, sta32x_limiter_attack_rate); +-static const struct soc_enum sta32x_limiter1_release_rate_enum = +- SOC_ENUM_SINGLE(STA32X_L1AR, STA32X_LxR_SHIFT, +- 16, sta32x_limiter_release_rate); +-static const struct soc_enum sta32x_limiter2_release_rate_enum = +- SOC_ENUM_SINGLE(STA32X_L2AR, STA32X_LxR_SHIFT, +- 16, sta32x_limiter_release_rate); ++static SOC_ENUM_SINGLE_DECL(sta32x_drc_ac_enum, ++ STA32X_CONFD, STA32X_CONFD_DRC_SHIFT, ++ sta32x_drc_ac); ++static SOC_ENUM_SINGLE_DECL(sta32x_auto_eq_enum, ++ STA32X_AUTO1, STA32X_AUTO1_AMEQ_SHIFT, ++ sta32x_auto_eq_mode); ++static SOC_ENUM_SINGLE_DECL(sta32x_auto_gc_enum, ++ STA32X_AUTO1, STA32X_AUTO1_AMGC_SHIFT, ++ sta32x_auto_gc_mode); ++static SOC_ENUM_SINGLE_DECL(sta32x_auto_xo_enum, ++ STA32X_AUTO2, STA32X_AUTO2_XO_SHIFT, ++ sta32x_auto_xo_mode); ++static SOC_ENUM_SINGLE_DECL(sta32x_preset_eq_enum, ++ STA32X_AUTO3, STA32X_AUTO3_PEQ_SHIFT, ++ sta32x_preset_eq_mode); ++static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch1_enum, ++ STA32X_C1CFG, STA32X_CxCFG_LS_SHIFT, ++ sta32x_limiter_select); ++static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch2_enum, ++ STA32X_C2CFG, STA32X_CxCFG_LS_SHIFT, ++ sta32x_limiter_select); ++static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch3_enum, ++ STA32X_C3CFG, STA32X_CxCFG_LS_SHIFT, ++ sta32x_limiter_select); ++static SOC_ENUM_SINGLE_DECL(sta32x_limiter1_attack_rate_enum, ++ STA32X_L1AR, STA32X_LxA_SHIFT, ++ sta32x_limiter_attack_rate); ++static SOC_ENUM_SINGLE_DECL(sta32x_limiter2_attack_rate_enum, ++ STA32X_L2AR, STA32X_LxA_SHIFT, ++ sta32x_limiter_attack_rate); ++static SOC_ENUM_SINGLE_DECL(sta32x_limiter1_release_rate_enum, ++ STA32X_L1AR, STA32X_LxR_SHIFT, ++ sta32x_limiter_release_rate); ++static SOC_ENUM_SINGLE_DECL(sta32x_limiter2_release_rate_enum, ++ STA32X_L2AR, STA32X_LxR_SHIFT, ++ sta32x_limiter_release_rate); + + /* byte array controls for setting biquad, mixer, scaling coefficients; + * for biquads all five coefficients need to be set in one go, +@@ -394,7 +394,7 @@ SOC_SINGLE_TLV("Treble Tone Control", STA32X_TONE, STA32X_TONE_TTC_SHIFT, 15, 0, + SOC_ENUM("Limiter1 Attack Rate (dB/ms)", sta32x_limiter1_attack_rate_enum), + SOC_ENUM("Limiter2 Attack Rate (dB/ms)", sta32x_limiter2_attack_rate_enum), + SOC_ENUM("Limiter1 Release Rate (dB/ms)", sta32x_limiter1_release_rate_enum), +-SOC_ENUM("Limiter2 Release Rate (dB/ms)", sta32x_limiter1_release_rate_enum), ++SOC_ENUM("Limiter2 Release Rate (dB/ms)", sta32x_limiter2_release_rate_enum), + + /* depending on mode, the attack/release thresholds have + * two different enum definitions; provide both +diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c +index a5127b4ff9e1..9e82674ed0ca 100644 +--- a/sound/soc/codecs/wm8770.c ++++ b/sound/soc/codecs/wm8770.c +@@ -162,8 +162,8 @@ static const char *ain_text[] = { + "AIN5", "AIN6", "AIN7", "AIN8" + }; + +-static const struct soc_enum ain_enum = +- SOC_ENUM_DOUBLE(WM8770_ADCMUX, 0, 4, 8, ain_text); ++static SOC_ENUM_DOUBLE_DECL(ain_enum, ++ WM8770_ADCMUX, 0, 4, ain_text); + + static const struct snd_kcontrol_new ain_mux = + SOC_DAPM_ENUM("Capture Mux", ain_enum); +diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c +index 1332692ef81b..77552b5048cc 100644 +--- a/sound/soc/codecs/wm8958-dsp2.c ++++ b/sound/soc/codecs/wm8958-dsp2.c +@@ -153,7 +153,7 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name, + + data32 &= 0xffffff; + +- wm8994_bulk_write(codec->control_data, ++ wm8994_bulk_write(wm8994->wm8994, + data32 & 0xffffff, + block_len / 2, + (void *)(data + 8)); +diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c +index 4f81ed456325..30afae7baddf 100644 +--- a/sound/soc/imx/imx-ssi.c ++++ b/sound/soc/imx/imx-ssi.c +@@ -497,6 +497,8 @@ static void imx_ssi_ac97_reset(struct snd_ac97 *ac97) + + if (imx_ssi->ac97_reset) + imx_ssi->ac97_reset(ac97); ++ /* First read sometimes fails, do a dummy read */ ++ imx_ssi_ac97_read(ac97, 0); + } + + static void imx_ssi_ac97_warm_reset(struct snd_ac97 *ac97) +@@ -505,6 +507,9 @@ static void imx_ssi_ac97_warm_reset(struct snd_ac97 *ac97) + + if (imx_ssi->ac97_warm_reset) + imx_ssi->ac97_warm_reset(ac97); ++ ++ /* First read sometimes fails, do a dummy read */ ++ imx_ssi_ac97_read(ac97, 0); + } + + struct snd_ac97_bus_ops soc_ac97_ops = { +diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c +index 716da861c629..17f9348966b3 100644 +--- a/sound/soc/s6000/s6000-pcm.c ++++ b/sound/soc/s6000/s6000-pcm.c +@@ -128,7 +128,9 @@ static irqreturn_t s6000_pcm_irq(int irq, void *data) + substream->runtime && + snd_pcm_running(substream)) { + dev_dbg(pcm->dev, "xrun\n"); ++ snd_pcm_stream_lock(substream); + snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); ++ snd_pcm_stream_unlock(substream); + ret = IRQ_HANDLED; + } + +diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c +index 4da9ca9c81bf..7c4f311af0f1 100644 +--- a/sound/usb/6fire/pcm.c ++++ b/sound/usb/6fire/pcm.c +@@ -639,17 +639,25 @@ int __devinit usb6fire_pcm_init(struct sfire_chip *chip) + void usb6fire_pcm_abort(struct sfire_chip *chip) + { + struct pcm_runtime *rt = chip->pcm; ++ unsigned long flags; + int i; + + if (rt) { + rt->panic = true; + +- if (rt->playback.instance) ++ if (rt->playback.instance) { ++ snd_pcm_stream_lock_irqsave(rt->playback.instance, flags); + snd_pcm_stop(rt->playback.instance, + SNDRV_PCM_STATE_XRUN); +- if (rt->capture.instance) ++ snd_pcm_stream_unlock_irqrestore(rt->playback.instance, flags); ++ } ++ ++ if (rt->capture.instance) { ++ snd_pcm_stream_lock_irqsave(rt->capture.instance, flags); + snd_pcm_stop(rt->capture.instance, + SNDRV_PCM_STATE_XRUN); ++ snd_pcm_stream_unlock_irqrestore(rt->capture.instance, flags); ++ } + + for (i = 0; i < PCM_N_URBS; i++) { + usb_poison_urb(&rt->in_urbs[i].instance); +diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c +index 8b81cb54026f..d97d35da53f8 100644 +--- a/sound/usb/misc/ua101.c ++++ b/sound/usb/misc/ua101.c +@@ -613,14 +613,24 @@ static int start_usb_playback(struct ua101 *ua) + + static void abort_alsa_capture(struct ua101 *ua) + { +- if (test_bit(ALSA_CAPTURE_RUNNING, &ua->states)) ++ unsigned long flags; ++ ++ if (test_bit(ALSA_CAPTURE_RUNNING, &ua->states)) { ++ snd_pcm_stream_lock_irqsave(ua->capture.substream, flags); + snd_pcm_stop(ua->capture.substream, SNDRV_PCM_STATE_XRUN); ++ snd_pcm_stream_unlock_irqrestore(ua->capture.substream, flags); ++ } + } + + static void abort_alsa_playback(struct ua101 *ua) + { +- if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states)) ++ unsigned long flags; ++ ++ if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states)) { ++ snd_pcm_stream_lock_irqsave(ua->playback.substream, flags); + snd_pcm_stop(ua->playback.substream, SNDRV_PCM_STATE_XRUN); ++ snd_pcm_stream_unlock_irqrestore(ua->playback.substream, flags); ++ } + } + + static int set_stream_hw(struct ua101 *ua, struct snd_pcm_substream *substream, +diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c +index f1324c423835..0e4e909d111e 100644 +--- a/sound/usb/mixer_maps.c ++++ b/sound/usb/mixer_maps.c +@@ -304,6 +304,11 @@ static struct usbmix_name_map hercules_usb51_map[] = { + { 0 } /* terminator */ + }; + ++static const struct usbmix_name_map kef_x300a_map[] = { ++ { 10, NULL }, /* firmware locks up (?) when we try to access this FU */ ++ { 0 } ++}; ++ + /* + * Control map entries + */ +@@ -371,6 +376,10 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = { + .map = scratch_live_map, + .ignore_ctl_error = 1, + }, ++ { ++ .id = USB_ID(0x27ac, 0x1000), ++ .map = kef_x300a_map, ++ }, + { 0 } /* terminator */ + }; + +diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c +index 711299ccf261..bdc4ddb7a060 100644 +--- a/sound/usb/usx2y/usbusx2yaudio.c ++++ b/sound/usb/usx2y/usbusx2yaudio.c +@@ -273,7 +273,11 @@ static void usX2Y_clients_stop(struct usX2Ydev *usX2Y) + struct snd_usX2Y_substream *subs = usX2Y->subs[s]; + if (subs) { + if (atomic_read(&subs->state) >= state_PRERUNNING) { ++ unsigned long flags; ++ ++ snd_pcm_stream_lock_irqsave(subs->pcm_substream, flags); + snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN); ++ snd_pcm_stream_unlock_irqrestore(subs->pcm_substream, flags); + } + for (u = 0; u < NRURBS; u++) { + struct urb *urb = subs->urb[u]; +diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c +index 5b3a0ef4e232..808d94669d0d 100644 +--- a/tools/perf/util/parse-events.c ++++ b/tools/perf/util/parse-events.c +@@ -413,7 +413,7 @@ int parse_events_add_cache(struct list_head *list, int *idx, + for (i = 0; (i < 2) && (op_result[i]); i++) { + char *str = op_result[i]; + +- snprintf(name + n, MAX_NAME_LEN - n, "-%s\n", str); ++ n += snprintf(name + n, MAX_NAME_LEN - n, "-%s", str); + + if (cache_op == -1) { + cache_op = parse_aliases(str, hw_cache_op, +diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c +index e9fff9830bf0..53d34f626c15 100644 +--- a/virt/kvm/iommu.c ++++ b/virt/kvm/iommu.c +@@ -101,6 +101,10 @@ int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot) + while ((gfn << PAGE_SHIFT) & (page_size - 1)) + page_size >>= 1; + ++ /* Make sure hva is aligned to the page size we want to map */ ++ while (gfn_to_hva_memslot(slot, gfn) & (page_size - 1)) ++ page_size >>= 1; ++ + /* + * Pin all pages we are about to map in memory. This is + * important because we unmap and unpin in 4kb steps later. diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.83-84.patch b/patch/kernel/sun8i-default/0001-patch-3.4.83-84.patch new file mode 100644 index 000000000..8b94d20c4 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.83-84.patch @@ -0,0 +1,946 @@ +diff --git a/Makefile b/Makefile +index e677b662f8c5..f75a853f8524 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 83 ++SUBLEVEL = 84 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/arm/mach-sa1100/include/mach/collie.h b/arch/arm/mach-sa1100/include/mach/collie.h +index f33679d2d3ee..50e1d850ee2e 100644 +--- a/arch/arm/mach-sa1100/include/mach/collie.h ++++ b/arch/arm/mach-sa1100/include/mach/collie.h +@@ -13,6 +13,8 @@ + #ifndef __ASM_ARCH_COLLIE_H + #define __ASM_ARCH_COLLIE_H + ++#include "hardware.h" /* Gives GPIO_MAX */ ++ + extern void locomolcd_power(int on); + + #define COLLIE_SCOOP_GPIO_BASE (GPIO_MAX + 1) +diff --git a/arch/powerpc/kernel/reloc_64.S b/arch/powerpc/kernel/reloc_64.S +index b47a0e1ab001..c712ecec13ba 100644 +--- a/arch/powerpc/kernel/reloc_64.S ++++ b/arch/powerpc/kernel/reloc_64.S +@@ -81,6 +81,7 @@ _GLOBAL(relocate) + + 6: blr + ++.balign 8 + p_dyn: .llong __dynamic_start - 0b + p_rela: .llong __rela_dyn_start - 0b + p_st: .llong _stext - 0b +diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c +index 03920a15a632..28a3e62fcc50 100644 +--- a/arch/x86/kernel/quirks.c ++++ b/arch/x86/kernel/quirks.c +@@ -525,7 +525,7 @@ static void __init quirk_amd_nb_node(struct pci_dev *dev) + return; + + pci_read_config_dword(nb_ht, 0x60, &val); +- node = val & 7; ++ node = pcibus_to_node(dev->bus) | (val & 7); + /* + * Some hardware may return an invalid node ID, + * so check it first: +diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c +index e334389e1c75..b567285efceb 100644 +--- a/arch/x86/kvm/svm.c ++++ b/arch/x86/kvm/svm.c +@@ -3007,10 +3007,8 @@ static int cr8_write_interception(struct vcpu_svm *svm) + u8 cr8_prev = kvm_get_cr8(&svm->vcpu); + /* instruction emulation calls kvm_set_cr8() */ + r = cr_interception(svm); +- if (irqchip_in_kernel(svm->vcpu.kvm)) { +- clr_cr_intercept(svm, INTERCEPT_CR8_WRITE); ++ if (irqchip_in_kernel(svm->vcpu.kvm)) + return r; +- } + if (cr8_prev <= kvm_get_cr8(&svm->vcpu)) + return r; + kvm_run->exit_reason = KVM_EXIT_SET_TPR; +@@ -3566,6 +3564,8 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr) + if (is_guest_mode(vcpu) && (vcpu->arch.hflags & HF_VINTR_MASK)) + return; + ++ clr_cr_intercept(svm, INTERCEPT_CR8_WRITE); ++ + if (irr == -1) + return; + +diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c +index 400b8c6eb8eb..f2f37171e21a 100644 +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -4106,6 +4106,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { + + /* Seagate Momentus SpinPoint M8 seem to have FPMDA_AA issues */ + { "ST1000LM024 HN-M101MBB", "2AR10001", ATA_HORKAGE_BROKEN_FPDMA_AA }, ++ { "ST1000LM024 HN-M101MBB", "2BA30001", ATA_HORKAGE_BROKEN_FPDMA_AA }, + + /* Blacklist entries taken from Silicon Image 3124/3132 + Windows driver .inf file - also several Linux problem reports */ +diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c +index 04ebeaf8cffe..1026609dc32e 100644 +--- a/drivers/firewire/core-device.c ++++ b/drivers/firewire/core-device.c +@@ -878,7 +878,7 @@ static int lookup_existing_device(struct device *dev, void *data) + old->config_rom_retries = 0; + fw_notice(card, "rediscovered device %s\n", dev_name(dev)); + +- PREPARE_DELAYED_WORK(&old->work, fw_device_update); ++ old->workfn = fw_device_update; + fw_schedule_device_work(old, 0); + + if (current_node == card->root_node) +@@ -1040,7 +1040,7 @@ static void fw_device_init(struct work_struct *work) + if (atomic_cmpxchg(&device->state, + FW_DEVICE_INITIALIZING, + FW_DEVICE_RUNNING) == FW_DEVICE_GONE) { +- PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); ++ device->workfn = fw_device_shutdown; + fw_schedule_device_work(device, SHUTDOWN_DELAY); + } else { + fw_notice(card, "created device %s: GUID %08x%08x, S%d00\n", +@@ -1172,13 +1172,20 @@ static void fw_device_refresh(struct work_struct *work) + dev_name(&device->device)); + gone: + atomic_set(&device->state, FW_DEVICE_GONE); +- PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); ++ device->workfn = fw_device_shutdown; + fw_schedule_device_work(device, SHUTDOWN_DELAY); + out: + if (node_id == card->root_node->node_id) + fw_schedule_bm_work(card, 0); + } + ++static void fw_device_workfn(struct work_struct *work) ++{ ++ struct fw_device *device = container_of(to_delayed_work(work), ++ struct fw_device, work); ++ device->workfn(work); ++} ++ + void fw_node_event(struct fw_card *card, struct fw_node *node, int event) + { + struct fw_device *device; +@@ -1228,7 +1235,8 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) + * power-up after getting plugged in. We schedule the + * first config rom scan half a second after bus reset. + */ +- INIT_DELAYED_WORK(&device->work, fw_device_init); ++ device->workfn = fw_device_init; ++ INIT_DELAYED_WORK(&device->work, fw_device_workfn); + fw_schedule_device_work(device, INITIAL_DELAY); + break; + +@@ -1244,7 +1252,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) + if (atomic_cmpxchg(&device->state, + FW_DEVICE_RUNNING, + FW_DEVICE_INITIALIZING) == FW_DEVICE_RUNNING) { +- PREPARE_DELAYED_WORK(&device->work, fw_device_refresh); ++ device->workfn = fw_device_refresh; + fw_schedule_device_work(device, + device->is_local ? 0 : INITIAL_DELAY); + } +@@ -1259,7 +1267,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) + smp_wmb(); /* update node_id before generation */ + device->generation = card->generation; + if (atomic_read(&device->state) == FW_DEVICE_RUNNING) { +- PREPARE_DELAYED_WORK(&device->work, fw_device_update); ++ device->workfn = fw_device_update; + fw_schedule_device_work(device, 0); + } + break; +@@ -1284,7 +1292,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) + device = node->data; + if (atomic_xchg(&device->state, + FW_DEVICE_GONE) == FW_DEVICE_RUNNING) { +- PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); ++ device->workfn = fw_device_shutdown; + fw_schedule_device_work(device, + list_empty(&card->link) ? 0 : SHUTDOWN_DELAY); + } +diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c +index 638e1f71284a..7cff7f7e69e1 100644 +--- a/drivers/firewire/net.c ++++ b/drivers/firewire/net.c +@@ -1014,8 +1014,6 @@ static void fwnet_write_complete(struct fw_card *card, int rcode, + if (rcode == RCODE_COMPLETE) { + fwnet_transmit_packet_done(ptask); + } else { +- fwnet_transmit_packet_failed(ptask); +- + if (printk_timed_ratelimit(&j, 1000) || rcode != last_rcode) { + dev_err(&ptask->dev->netdev->dev, + "fwnet_write_complete failed: %x (skipped %d)\n", +@@ -1023,8 +1021,10 @@ static void fwnet_write_complete(struct fw_card *card, int rcode, + + errors_skipped = 0; + last_rcode = rcode; +- } else ++ } else { + errors_skipped++; ++ } ++ fwnet_transmit_packet_failed(ptask); + } + } + +diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c +index b7e65d7eab64..23a928352498 100644 +--- a/drivers/firewire/sbp2.c ++++ b/drivers/firewire/sbp2.c +@@ -146,6 +146,7 @@ struct sbp2_logical_unit { + */ + int generation; + int retries; ++ work_func_t workfn; + struct delayed_work work; + bool has_sdev; + bool blocked; +@@ -865,7 +866,7 @@ static void sbp2_login(struct work_struct *work) + /* set appropriate retry limit(s) in BUSY_TIMEOUT register */ + sbp2_set_busy_timeout(lu); + +- PREPARE_DELAYED_WORK(&lu->work, sbp2_reconnect); ++ lu->workfn = sbp2_reconnect; + sbp2_agent_reset(lu); + + /* This was a re-login. */ +@@ -919,7 +920,7 @@ static void sbp2_login(struct work_struct *work) + * If a bus reset happened, sbp2_update will have requeued + * lu->work already. Reset the work from reconnect to login. + */ +- PREPARE_DELAYED_WORK(&lu->work, sbp2_login); ++ lu->workfn = sbp2_login; + } + + static void sbp2_reconnect(struct work_struct *work) +@@ -953,7 +954,7 @@ static void sbp2_reconnect(struct work_struct *work) + lu->retries++ >= 5) { + dev_err(tgt_dev(tgt), "failed to reconnect\n"); + lu->retries = 0; +- PREPARE_DELAYED_WORK(&lu->work, sbp2_login); ++ lu->workfn = sbp2_login; + } + sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5)); + +@@ -973,6 +974,13 @@ static void sbp2_reconnect(struct work_struct *work) + sbp2_conditionally_unblock(lu); + } + ++static void sbp2_lu_workfn(struct work_struct *work) ++{ ++ struct sbp2_logical_unit *lu = container_of(to_delayed_work(work), ++ struct sbp2_logical_unit, work); ++ lu->workfn(work); ++} ++ + static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry) + { + struct sbp2_logical_unit *lu; +@@ -999,7 +1007,8 @@ static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry) + lu->blocked = false; + ++tgt->dont_block; + INIT_LIST_HEAD(&lu->orb_list); +- INIT_DELAYED_WORK(&lu->work, sbp2_login); ++ lu->workfn = sbp2_login; ++ INIT_DELAYED_WORK(&lu->work, sbp2_lu_workfn); + + list_add_tail(&lu->link, &tgt->lu_list); + return 0; +diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c +index 6f4627fe24a1..072229dca464 100644 +--- a/drivers/gpu/drm/radeon/atombios_encoders.c ++++ b/drivers/gpu/drm/radeon/atombios_encoders.c +@@ -1048,7 +1048,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t + } + if (is_dp) + args.v5.ucLaneNum = dp_lane_count; +- else if (radeon_encoder->pixel_clock > 165000) ++ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) + args.v5.ucLaneNum = 8; + else + args.v5.ucLaneNum = 4; +diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c +index 8b73ae84efe7..ceb70dde21ab 100644 +--- a/drivers/gpu/drm/ttm/ttm_bo.c ++++ b/drivers/gpu/drm/ttm/ttm_bo.c +@@ -430,9 +430,11 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, + + moved: + if (bo->evicted) { +- ret = bdev->driver->invalidate_caches(bdev, bo->mem.placement); +- if (ret) +- pr_err("Can not flush read caches\n"); ++ if (bdev->driver->invalidate_caches) { ++ ret = bdev->driver->invalidate_caches(bdev, bo->mem.placement); ++ if (ret) ++ pr_err("Can not flush read caches\n"); ++ } + bo->evicted = false; + } + +diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c +index eb4014a25d3c..75e9233aabaf 100644 +--- a/drivers/net/can/flexcan.c ++++ b/drivers/net/can/flexcan.c +@@ -805,7 +805,7 @@ static int flexcan_open(struct net_device *dev) + + err = request_irq(dev->irq, flexcan_irq, IRQF_SHARED, dev->name, dev); + if (err) +- goto out_close; ++ goto out_free_irq; + + /* start chip and queuing */ + err = flexcan_chip_start(dev); +@@ -816,6 +816,8 @@ static int flexcan_open(struct net_device *dev) + + return 0; + ++ out_free_irq: ++ free_irq(dev->irq, dev); + out_close: + close_candev(dev); + out: +diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c +index 558974f466de..6f4604958d63 100644 +--- a/drivers/net/ethernet/broadcom/tg3.c ++++ b/drivers/net/ethernet/broadcom/tg3.c +@@ -5844,8 +5844,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) + + work_mask |= opaque_key; + +- if ((desc->err_vlan & RXD_ERR_MASK) != 0 && +- (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII)) { ++ if (desc->err_vlan & RXD_ERR_MASK) { + drop_it: + tg3_recycle_rx(tnapi, tpr, opaque_key, + desc_idx, *post_ptr); +diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h +index 93865f899a4f..780604de73f4 100644 +--- a/drivers/net/ethernet/broadcom/tg3.h ++++ b/drivers/net/ethernet/broadcom/tg3.h +@@ -2484,7 +2484,11 @@ struct tg3_rx_buffer_desc { + #define RXD_ERR_TOO_SMALL 0x00400000 + #define RXD_ERR_NO_RESOURCES 0x00800000 + #define RXD_ERR_HUGE_FRAME 0x01000000 +-#define RXD_ERR_MASK 0xffff0000 ++ ++#define RXD_ERR_MASK (RXD_ERR_BAD_CRC | RXD_ERR_COLLISION | \ ++ RXD_ERR_LINK_LOST | RXD_ERR_PHY_DECODE | \ ++ RXD_ERR_MAC_ABRT | RXD_ERR_TOO_SMALL | \ ++ RXD_ERR_NO_RESOURCES | RXD_ERR_HUGE_FRAME) + + u32 reserved; + u32 opaque; +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index bc177b996f4c..efb50d6dfb6c 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -1084,7 +1084,8 @@ static int virtnet_probe(struct virtio_device *vdev) + /* If we can receive ANY GSO packets, we must allocate large ones. */ + if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) || + virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) || +- virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN)) ++ virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN) || ++ virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_UFO)) + vi->big_packets = true; + + if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF)) +diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c +index 3f04ba0a5454..d43df93dc83a 100644 +--- a/drivers/net/vmxnet3/vmxnet3_drv.c ++++ b/drivers/net/vmxnet3/vmxnet3_drv.c +@@ -1729,11 +1729,20 @@ vmxnet3_netpoll(struct net_device *netdev) + { + struct vmxnet3_adapter *adapter = netdev_priv(netdev); + +- if (adapter->intr.mask_mode == VMXNET3_IMM_ACTIVE) +- vmxnet3_disable_all_intrs(adapter); +- +- vmxnet3_do_poll(adapter, adapter->rx_queue[0].rx_ring[0].size); +- vmxnet3_enable_all_intrs(adapter); ++ switch (adapter->intr.type) { ++#ifdef CONFIG_PCI_MSI ++ case VMXNET3_IT_MSIX: { ++ int i; ++ for (i = 0; i < adapter->num_rx_queues; i++) ++ vmxnet3_msix_rx(0, &adapter->rx_queue[i]); ++ break; ++ } ++#endif ++ case VMXNET3_IT_MSI: ++ default: ++ vmxnet3_intr(0, adapter->netdev); ++ break; ++ } + + } + #endif /* CONFIG_NET_POLL_CONTROLLER */ +diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +index b6ba1e8149be..15960024d4a0 100644 +--- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h ++++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +@@ -55,7 +55,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { + {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3376605e, 0x33795d5e}, + {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, +- {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, ++ {0x00009e20, 0x000003a5, 0x000003a5, 0x000003a5, 0x000003a5}, + {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, + {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282}, + {0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27}, +@@ -94,7 +94,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { + {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x00100000}, + {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, +- {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, ++ {0x0000ae20, 0x000001a6, 0x000001a6, 0x000001aa, 0x000001aa}, + {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, + }; + +diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c +index a5e182b5e944..6f882bcf96f1 100644 +--- a/drivers/net/wireless/mwifiex/11n.c ++++ b/drivers/net/wireless/mwifiex/11n.c +@@ -340,8 +340,7 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, + ht_cap->header.len = + cpu_to_le16(sizeof(struct ieee80211_ht_cap)); + memcpy((u8 *) ht_cap + sizeof(struct mwifiex_ie_types_header), +- (u8 *) bss_desc->bcn_ht_cap + +- sizeof(struct ieee_types_header), ++ (u8 *)bss_desc->bcn_ht_cap, + le16_to_cpu(ht_cap->header.len)); + + mwifiex_fill_cap_info(priv, radio_type, ht_cap); +diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h +index adbad69d1069..15bd1a42f236 100644 +--- a/drivers/scsi/isci/host.h ++++ b/drivers/scsi/isci/host.h +@@ -310,9 +310,8 @@ static inline struct isci_pci_info *to_pci_info(struct pci_dev *pdev) + } + + #define for_each_isci_host(id, ihost, pdev) \ +- for (id = 0, ihost = to_pci_info(pdev)->hosts[id]; \ +- id < ARRAY_SIZE(to_pci_info(pdev)->hosts) && ihost; \ +- ihost = to_pci_info(pdev)->hosts[++id]) ++ for (id = 0; id < SCI_MAX_CONTROLLERS && \ ++ (ihost = to_pci_info(pdev)->hosts[id]); id++) + + static inline enum isci_status isci_host_get_state(struct isci_host *isci_host) + { +diff --git a/drivers/scsi/isci/port_config.c b/drivers/scsi/isci/port_config.c +index 6d1e9544cbe5..b81f34ddc025 100644 +--- a/drivers/scsi/isci/port_config.c ++++ b/drivers/scsi/isci/port_config.c +@@ -619,13 +619,6 @@ static void sci_apc_agent_link_up(struct isci_host *ihost, + SCIC_SDS_APC_WAIT_LINK_UP_NOTIFICATION); + } else { + /* the phy is already the part of the port */ +- u32 port_state = iport->sm.current_state_id; +- +- /* if the PORT'S state is resetting then the link up is from +- * port hard reset in this case, we need to tell the port +- * that link up is recieved +- */ +- BUG_ON(port_state != SCI_PORT_RESETTING); + port_agent->phy_ready_mask |= 1 << phy_index; + sci_port_link_up(iport, iphy); + } +diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c +index 374254ede9d4..2a81e1793e5d 100644 +--- a/drivers/scsi/isci/task.c ++++ b/drivers/scsi/isci/task.c +@@ -1312,7 +1312,7 @@ int isci_task_I_T_nexus_reset(struct domain_device *dev) + /* XXX: need to cleanup any ireqs targeting this + * domain_device + */ +- ret = TMF_RESP_FUNC_COMPLETE; ++ ret = -ENODEV; + goto out; + } + +diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h +index a2443031dbe7..09bedb7f47e9 100644 +--- a/drivers/scsi/qla2xxx/qla_def.h ++++ b/drivers/scsi/qla2xxx/qla_def.h +@@ -2600,8 +2600,7 @@ struct qla_hw_data { + IS_QLA25XX(ha) || IS_QLA81XX(ha) || \ + IS_QLA82XX(ha) || IS_QLA83XX(ha)) + #define IS_MSIX_NACK_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha)) +-#define IS_NOPOLLING_TYPE(ha) ((IS_QLA25XX(ha) || IS_QLA81XX(ha) || \ +- IS_QLA83XX(ha)) && (ha)->flags.msix_enabled) ++#define IS_NOPOLLING_TYPE(ha) (IS_QLA81XX(ha) && (ha)->flags.msix_enabled) + #define IS_FAC_REQUIRED(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha)) + #define IS_NOCACHE_VPD_TYPE(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha)) + #define IS_ALOGIO_CAPABLE(ha) (IS_QLA23XX(ha) || IS_FWI2_CAPABLE(ha)) +diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c +index f9986ccbd80c..446c02379c80 100644 +--- a/drivers/scsi/storvsc_drv.c ++++ b/drivers/scsi/storvsc_drv.c +@@ -1131,6 +1131,9 @@ static void storvsc_device_destroy(struct scsi_device *sdevice) + { + struct stor_mem_pools *memp = sdevice->hostdata; + ++ if (!memp) ++ return; ++ + mempool_destroy(memp->request_mempool); + kmem_cache_destroy(memp->request_pool); + kfree(memp); +diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c +index 86eff48dab78..503a6bdc1d17 100644 +--- a/fs/btrfs/compression.c ++++ b/fs/btrfs/compression.c +@@ -995,6 +995,8 @@ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start, + bytes = min(bytes, working_bytes); + kaddr = kmap_atomic(page_out); + memcpy(kaddr + *pg_offset, buf + buf_offset, bytes); ++ if (*pg_index == (vcnt - 1) && *pg_offset == 0) ++ memset(kaddr + bytes, 0, PAGE_CACHE_SIZE - bytes); + kunmap_atomic(kaddr); + flush_dcache_page(page_out); + +diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c +index 89af1d269274..16d16e56cc39 100644 +--- a/fs/nfs/delegation.c ++++ b/fs/nfs/delegation.c +@@ -540,16 +540,19 @@ int nfs_async_inode_return_delegation(struct inode *inode, + + rcu_read_lock(); + delegation = rcu_dereference(NFS_I(inode)->delegation); ++ if (delegation == NULL) ++ goto out_enoent; + +- if (!clp->cl_mvops->match_stateid(&delegation->stateid, stateid)) { +- rcu_read_unlock(); +- return -ENOENT; +- } ++ if (!clp->cl_mvops->match_stateid(&delegation->stateid, stateid)) ++ goto out_enoent; + nfs_mark_return_delegation(server, delegation); + rcu_read_unlock(); + + nfs_delegation_run_state_manager(clp); + return 0; ++out_enoent: ++ rcu_read_unlock(); ++ return -ENOENT; + } + + static struct inode * +diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c +index 7602783d7f41..8021098ff507 100644 +--- a/fs/ocfs2/file.c ++++ b/fs/ocfs2/file.c +@@ -2389,8 +2389,8 @@ out_dio: + + if (((file->f_flags & O_DSYNC) && !direct_io) || IS_SYNC(inode) || + ((file->f_flags & O_DIRECT) && !direct_io)) { +- ret = filemap_fdatawrite_range(file->f_mapping, pos, +- pos + count - 1); ++ ret = filemap_fdatawrite_range(file->f_mapping, *ppos, ++ *ppos + count - 1); + if (ret < 0) + written = ret; + +@@ -2403,8 +2403,8 @@ out_dio: + } + + if (!ret) +- ret = filemap_fdatawait_range(file->f_mapping, pos, +- pos + count - 1); ++ ret = filemap_fdatawait_range(file->f_mapping, *ppos, ++ *ppos + count - 1); + } + + /* +diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c +index 92fcd575775a..a40e5cedd6d4 100644 +--- a/fs/ocfs2/quota_global.c ++++ b/fs/ocfs2/quota_global.c +@@ -712,6 +712,12 @@ static int ocfs2_release_dquot(struct dquot *dquot) + */ + if (status < 0) + mlog_errno(status); ++ /* ++ * Clear dq_off so that we search for the structure in quota file next ++ * time we acquire it. The structure might be deleted and reallocated ++ * elsewhere by another node while our dquot structure is on freelist. ++ */ ++ dquot->dq_off = 0; + clear_bit(DQ_ACTIVE_B, &dquot->dq_flags); + out_trans: + ocfs2_commit_trans(osb, handle); +@@ -750,16 +756,17 @@ static int ocfs2_acquire_dquot(struct dquot *dquot) + status = ocfs2_lock_global_qf(info, 1); + if (status < 0) + goto out; +- if (!test_bit(DQ_READ_B, &dquot->dq_flags)) { +- status = ocfs2_qinfo_lock(info, 0); +- if (status < 0) +- goto out_dq; +- status = qtree_read_dquot(&info->dqi_gi, dquot); +- ocfs2_qinfo_unlock(info, 0); +- if (status < 0) +- goto out_dq; +- } +- set_bit(DQ_READ_B, &dquot->dq_flags); ++ status = ocfs2_qinfo_lock(info, 0); ++ if (status < 0) ++ goto out_dq; ++ /* ++ * We always want to read dquot structure from disk because we don't ++ * know what happened with it while it was on freelist. ++ */ ++ status = qtree_read_dquot(&info->dqi_gi, dquot); ++ ocfs2_qinfo_unlock(info, 0); ++ if (status < 0) ++ goto out_dq; + + OCFS2_DQUOT(dquot)->dq_use_count++; + OCFS2_DQUOT(dquot)->dq_origspace = dquot->dq_dqb.dqb_curspace; +diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c +index f100bf70a906..b6cfcf263d7f 100644 +--- a/fs/ocfs2/quota_local.c ++++ b/fs/ocfs2/quota_local.c +@@ -1300,10 +1300,6 @@ int ocfs2_local_release_dquot(handle_t *handle, struct dquot *dquot) + ocfs2_journal_dirty(handle, od->dq_chunk->qc_headerbh); + + out: +- /* Clear the read bit so that next time someone uses this +- * dquot he reads fresh info from disk and allocates local +- * dquot structure */ +- clear_bit(DQ_READ_B, &dquot->dq_flags); + return status; + } + +diff --git a/fs/proc/base.c b/fs/proc/base.c +index 9fc77b412ac4..754ac4ddd826 100644 +--- a/fs/proc/base.c ++++ b/fs/proc/base.c +@@ -2092,6 +2092,7 @@ static int proc_map_files_get_link(struct dentry *dentry, struct path *path) + if (rc) + goto out_mmput; + ++ rc = -ENOENT; + down_read(&mm->mmap_sem); + vma = find_exact_vma(mm, vm_start, vm_end); + if (vma && vma->vm_file) { +diff --git a/include/linux/firewire.h b/include/linux/firewire.h +index 4d259fc7722c..66e013b7c9f2 100644 +--- a/include/linux/firewire.h ++++ b/include/linux/firewire.h +@@ -186,6 +186,7 @@ struct fw_device { + unsigned irmc:1; + unsigned bc_implemented:2; + ++ work_func_t workfn; + struct delayed_work work; + struct fw_attribute_group attribute_group; + }; +diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h +index 265e2c3cbd1c..f5df3dcfe811 100644 +--- a/include/linux/jiffies.h ++++ b/include/linux/jiffies.h +@@ -106,13 +106,13 @@ static inline u64 get_jiffies_64(void) + #define time_after(a,b) \ + (typecheck(unsigned long, a) && \ + typecheck(unsigned long, b) && \ +- ((long)(b) - (long)(a) < 0)) ++ ((long)((b) - (a)) < 0)) + #define time_before(a,b) time_after(b,a) + + #define time_after_eq(a,b) \ + (typecheck(unsigned long, a) && \ + typecheck(unsigned long, b) && \ +- ((long)(a) - (long)(b) >= 0)) ++ ((long)((a) - (b)) >= 0)) + #define time_before_eq(a,b) time_after_eq(b,a) + + /* +@@ -135,13 +135,13 @@ static inline u64 get_jiffies_64(void) + #define time_after64(a,b) \ + (typecheck(__u64, a) && \ + typecheck(__u64, b) && \ +- ((__s64)(b) - (__s64)(a) < 0)) ++ ((__s64)((b) - (a)) < 0)) + #define time_before64(a,b) time_after64(b,a) + + #define time_after_eq64(a,b) \ + (typecheck(__u64, a) && \ + typecheck(__u64, b) && \ +- ((__s64)(a) - (__s64)(b) >= 0)) ++ ((__s64)((a) - (b)) >= 0)) + #define time_before_eq64(a,b) time_after_eq64(b,a) + + /* +diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h +index bd96ecd0e05c..c49c363f5bfd 100644 +--- a/include/linux/tracepoint.h ++++ b/include/linux/tracepoint.h +@@ -60,6 +60,12 @@ struct tp_module { + unsigned int num_tracepoints; + struct tracepoint * const *tracepoints_ptrs; + }; ++bool trace_module_has_bad_taint(struct module *mod); ++#else ++static inline bool trace_module_has_bad_taint(struct module *mod) ++{ ++ return false; ++} + #endif /* CONFIG_MODULES */ + + struct tracepoint_iter { +diff --git a/kernel/cpuset.c b/kernel/cpuset.c +index e372d9495e42..4b843ace285c 100644 +--- a/kernel/cpuset.c ++++ b/kernel/cpuset.c +@@ -2338,9 +2338,9 @@ int __cpuset_node_allowed_softwall(int node, gfp_t gfp_mask) + + task_lock(current); + cs = nearest_hardwall_ancestor(task_cs(current)); ++ allowed = node_isset(node, cs->mems_allowed); + task_unlock(current); + +- allowed = node_isset(node, cs->mems_allowed); + mutex_unlock(&callback_mutex); + return allowed; + } +diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c +index 86a500d7ea59..3d1bbbcc2923 100644 +--- a/kernel/irq/manage.c ++++ b/kernel/irq/manage.c +@@ -777,8 +777,7 @@ static irqreturn_t irq_thread_fn(struct irq_desc *desc, + + static void wake_threads_waitq(struct irq_desc *desc) + { +- if (atomic_dec_and_test(&desc->threads_active) && +- waitqueue_active(&desc->wait_for_threads)) ++ if (atomic_dec_and_test(&desc->threads_active)) + wake_up(&desc->wait_for_threads); + } + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index dd33c9fd8009..d21498e3c503 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -5270,15 +5270,15 @@ static void switched_from_fair(struct rq *rq, struct task_struct *p) + struct cfs_rq *cfs_rq = cfs_rq_of(se); + + /* +- * Ensure the task's vruntime is normalized, so that when its ++ * Ensure the task's vruntime is normalized, so that when it's + * switched back to the fair class the enqueue_entity(.flags=0) will + * do the right thing. + * +- * If it was on_rq, then the dequeue_entity(.flags=0) will already +- * have normalized the vruntime, if it was !on_rq, then only when ++ * If it's on_rq, then the dequeue_entity(.flags=0) will already ++ * have normalized the vruntime, if it's !on_rq, then only when + * the task is sleeping will it still have non-normalized vruntime. + */ +- if (!se->on_rq && p->state != TASK_RUNNING) { ++ if (!p->on_rq && p->state != TASK_RUNNING) { + /* + * Fix up our vruntime so that the current sleep doesn't + * cause 'unlimited' sleep bonus. +diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c +index 29111da1d100..2f737f536c27 100644 +--- a/kernel/trace/trace_events.c ++++ b/kernel/trace/trace_events.c +@@ -1354,6 +1354,16 @@ static void trace_module_add_events(struct module *mod) + struct ftrace_module_file_ops *file_ops = NULL; + struct ftrace_event_call **call, **start, **end; + ++ if (!mod->num_trace_events) ++ return; ++ ++ /* Don't add infrastructure for mods without tracepoints */ ++ if (trace_module_has_bad_taint(mod)) { ++ pr_err("%s: module has bad taint, not creating trace events\n", ++ mod->name); ++ return; ++ } ++ + start = mod->trace_events; + end = mod->trace_events + mod->num_trace_events; + +diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c +index d96ba22dabfa..23d8560dbc56 100644 +--- a/kernel/tracepoint.c ++++ b/kernel/tracepoint.c +@@ -628,6 +628,11 @@ void tracepoint_iter_reset(struct tracepoint_iter *iter) + EXPORT_SYMBOL_GPL(tracepoint_iter_reset); + + #ifdef CONFIG_MODULES ++bool trace_module_has_bad_taint(struct module *mod) ++{ ++ return mod->taints & ~((1 << TAINT_OOT_MODULE) | (1 << TAINT_CRAP)); ++} ++ + static int tracepoint_module_coming(struct module *mod) + { + struct tp_module *tp_mod, *iter; +@@ -638,7 +643,7 @@ static int tracepoint_module_coming(struct module *mod) + * module headers (for forced load), to make sure we don't cause a crash. + * Staging and out-of-tree GPL modules are fine. + */ +- if (mod->taints & ~((1 << TAINT_OOT_MODULE) | (1 << TAINT_CRAP))) ++ if (trace_module_has_bad_taint(mod)) + return 0; + mutex_lock(&tracepoints_mutex); + tp_mod = kmalloc(sizeof(struct tp_module), GFP_KERNEL); +diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c +index e2e0e0bc6622..569eb2cef3c9 100644 +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -242,6 +242,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, + return NULL; + + spin_lock_init(&sta->lock); ++ spin_lock_init(&sta->ps_lock); + INIT_WORK(&sta->drv_unblock_wk, sta_unblock); + INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work); + mutex_init(&sta->ampdu_mlme.mtx); +@@ -971,6 +972,8 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) + + skb_queue_head_init(&pending); + ++ /* sync with ieee80211_tx_h_unicast_ps_buf */ ++ spin_lock(&sta->ps_lock); + /* Send all buffered frames to the station */ + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { + int count = skb_queue_len(&pending), tmp; +@@ -990,6 +993,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) + } + + ieee80211_add_pending_skbs_fn(local, &pending, clear_sta_ps_flags, sta); ++ spin_unlock(&sta->ps_lock); + + local->total_ps_buffered -= buffered; + +diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h +index ab0576827baf..249f4d087936 100644 +--- a/net/mac80211/sta_info.h ++++ b/net/mac80211/sta_info.h +@@ -227,6 +227,7 @@ struct sta_ampdu_mlme { + * @drv_unblock_wk: used for driver PS unblocking + * @listen_interval: listen interval of this station, when we're acting as AP + * @_flags: STA flags, see &enum ieee80211_sta_info_flags, do not use directly ++ * @ps_lock: used for powersave (when mac80211 is the AP) related locking + * @ps_tx_buf: buffers (per AC) of frames to transmit to this station + * when it leaves power saving state or polls + * @tx_filtered: buffers (per AC) of frames we already tried to +@@ -297,10 +298,8 @@ struct sta_info { + /* use the accessors defined below */ + unsigned long _flags; + +- /* +- * STA powersave frame queues, no more than the internal +- * locking required. +- */ ++ /* STA powersave lock and frame queues */ ++ spinlock_t ps_lock; + struct sk_buff_head ps_tx_buf[IEEE80211_NUM_ACS]; + struct sk_buff_head tx_filtered[IEEE80211_NUM_ACS]; + unsigned long driver_buffered_tids; +diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c +index e4b7188a0572..b7fc3dd4b8ef 100644 +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -471,6 +471,20 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) + #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ + if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) + purge_old_ps_buffers(tx->local); ++ ++ /* sync with ieee80211_sta_ps_deliver_wakeup */ ++ spin_lock(&sta->ps_lock); ++ /* ++ * STA woke up the meantime and all the frames on ps_tx_buf have ++ * been queued to pending queue. No reordering can happen, go ++ * ahead and Tx the packet. ++ */ ++ if (!test_sta_flag(sta, WLAN_STA_PS_STA) && ++ !test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { ++ spin_unlock(&sta->ps_lock); ++ return TX_CONTINUE; ++ } ++ + if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) { + struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]); + #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG +@@ -487,6 +501,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) + info->control.vif = &tx->sdata->vif; + info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; + skb_queue_tail(&sta->ps_tx_buf[ac], tx->skb); ++ spin_unlock(&sta->ps_lock); + + if (!timer_pending(&local->sta_cleanup)) + mod_timer(&local->sta_cleanup, +diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c +index cb1c4303a07a..f131caf06a19 100644 +--- a/net/sctp/sm_statefuns.c ++++ b/net/sctp/sm_statefuns.c +@@ -747,6 +747,13 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep, + struct sctp_chunk auth; + sctp_ierror_t ret; + ++ /* Make sure that we and the peer are AUTH capable */ ++ if (!sctp_auth_enable || !new_asoc->peer.auth_capable) { ++ kfree_skb(chunk->auth_chunk); ++ sctp_association_free(new_asoc); ++ return sctp_sf_pdiscard(ep, asoc, type, arg, commands); ++ } ++ + /* set-up our fake chunk so that we can process it */ + auth.skb = chunk->auth_chunk; + auth.asoc = chunk->asoc; +diff --git a/sound/pci/oxygen/xonar_dg.c b/sound/pci/oxygen/xonar_dg.c +index 793bdf03d7e0..71527467de05 100644 +--- a/sound/pci/oxygen/xonar_dg.c ++++ b/sound/pci/oxygen/xonar_dg.c +@@ -294,6 +294,16 @@ static int output_switch_put(struct snd_kcontrol *ctl, + oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, + data->output_sel == 1 ? GPIO_HP_REAR : 0, + GPIO_HP_REAR); ++ oxygen_write8_masked(chip, OXYGEN_PLAY_ROUTING, ++ data->output_sel == 0 ? ++ OXYGEN_PLAY_MUTE01 : ++ OXYGEN_PLAY_MUTE23 | ++ OXYGEN_PLAY_MUTE45 | ++ OXYGEN_PLAY_MUTE67, ++ OXYGEN_PLAY_MUTE01 | ++ OXYGEN_PLAY_MUTE23 | ++ OXYGEN_PLAY_MUTE45 | ++ OXYGEN_PLAY_MUTE67); + } + mutex_unlock(&chip->mutex); + return changed; +@@ -597,7 +607,7 @@ struct oxygen_model model_xonar_dg = { + .model_data_size = sizeof(struct dg), + .device_config = PLAYBACK_0_TO_I2S | + PLAYBACK_1_TO_SPDIF | +- CAPTURE_0_FROM_I2S_2 | ++ CAPTURE_0_FROM_I2S_1 | + CAPTURE_1_FROM_SPDIF, + .dac_channels_pcm = 6, + .dac_channels_mixer = 0, +diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c +index 5ca46525d47e..30515583cab3 100644 +--- a/sound/usb/mixer.c ++++ b/sound/usb/mixer.c +@@ -819,6 +819,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, + } + break; + ++ case USB_ID(0x046d, 0x0807): /* Logitech Webcam C500 */ + case USB_ID(0x046d, 0x0808): + case USB_ID(0x046d, 0x0809): + case USB_ID(0x046d, 0x081b): /* HD Webcam c310 */ diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.84-85.patch b/patch/kernel/sun8i-default/0001-patch-3.4.84-85.patch new file mode 100644 index 000000000..f97681ed4 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.84-85.patch @@ -0,0 +1,403 @@ +diff --git a/Makefile b/Makefile +index f75a853f8524..66ae2984a38c 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 84 ++SUBLEVEL = 85 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h +index 53426c66352a..2dd513bdca23 100644 +--- a/arch/arm/include/asm/outercache.h ++++ b/arch/arm/include/asm/outercache.h +@@ -37,10 +37,10 @@ struct outer_cache_fns { + void (*resume)(void); + }; + +-#ifdef CONFIG_OUTER_CACHE +- + extern struct outer_cache_fns outer_cache; + ++#ifdef CONFIG_OUTER_CACHE ++ + static inline void outer_inv_range(phys_addr_t start, phys_addr_t end) + { + if (outer_cache.inv_range) +diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c +index 4cb164268846..fd6dec6ffa47 100644 +--- a/arch/x86/kvm/mmu.c ++++ b/arch/x86/kvm/mmu.c +@@ -2451,6 +2451,9 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write, + int emulate = 0; + gfn_t pseudo_gfn; + ++ if (!VALID_PAGE(vcpu->arch.mmu.root_hpa)) ++ return 0; ++ + for_each_shadow_entry(vcpu, (u64)gfn << PAGE_SHIFT, iterator) { + if (iterator.level == level) { + unsigned pte_access = ACC_ALL; +diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c +index 90f5c0ed9d2f..617b00b4857b 100644 +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -6281,8 +6281,8 @@ static void vmx_free_vcpu(struct kvm_vcpu *vcpu) + struct vcpu_vmx *vmx = to_vmx(vcpu); + + free_vpid(vmx); +- free_nested(vmx); + free_loaded_vmcs(vmx->loaded_vmcs); ++ free_nested(vmx); + kfree(vmx->guest_msrs); + kvm_vcpu_uninit(vcpu); + kmem_cache_free(kvm_vcpu_cache, vmx); +diff --git a/arch/x86/net/bpf_jit.S b/arch/x86/net/bpf_jit.S +index 877b9a1b2152..01495755701b 100644 +--- a/arch/x86/net/bpf_jit.S ++++ b/arch/x86/net/bpf_jit.S +@@ -140,7 +140,7 @@ bpf_slow_path_byte_msh: + push %r9; \ + push SKBDATA; \ + /* rsi already has offset */ \ +- mov $SIZE,%ecx; /* size */ \ ++ mov $SIZE,%edx; /* size */ \ + call bpf_internal_load_pointer_neg_helper; \ + test %rax,%rax; \ + pop SKBDATA; \ +diff --git a/drivers/edac/i7300_edac.c b/drivers/edac/i7300_edac.c +index f4059e9da301..8ba22ebff637 100644 +--- a/drivers/edac/i7300_edac.c ++++ b/drivers/edac/i7300_edac.c +@@ -962,33 +962,35 @@ static int __devinit i7300_get_devices(struct mem_ctl_info *mci) + + /* Attempt to 'get' the MCH register we want */ + pdev = NULL; +- while (!pvt->pci_dev_16_1_fsb_addr_map || +- !pvt->pci_dev_16_2_fsb_err_regs) { +- pdev = pci_get_device(PCI_VENDOR_ID_INTEL, +- PCI_DEVICE_ID_INTEL_I7300_MCH_ERR, pdev); +- if (!pdev) { +- /* End of list, leave */ +- i7300_printk(KERN_ERR, +- "'system address,Process Bus' " +- "device not found:" +- "vendor 0x%x device 0x%x ERR funcs " +- "(broken BIOS?)\n", +- PCI_VENDOR_ID_INTEL, +- PCI_DEVICE_ID_INTEL_I7300_MCH_ERR); +- goto error; +- } +- ++ while ((pdev = pci_get_device(PCI_VENDOR_ID_INTEL, ++ PCI_DEVICE_ID_INTEL_I7300_MCH_ERR, ++ pdev))) { + /* Store device 16 funcs 1 and 2 */ + switch (PCI_FUNC(pdev->devfn)) { + case 1: +- pvt->pci_dev_16_1_fsb_addr_map = pdev; ++ if (!pvt->pci_dev_16_1_fsb_addr_map) ++ pvt->pci_dev_16_1_fsb_addr_map = ++ pci_dev_get(pdev); + break; + case 2: +- pvt->pci_dev_16_2_fsb_err_regs = pdev; ++ if (!pvt->pci_dev_16_2_fsb_err_regs) ++ pvt->pci_dev_16_2_fsb_err_regs = ++ pci_dev_get(pdev); + break; + } + } + ++ if (!pvt->pci_dev_16_1_fsb_addr_map || ++ !pvt->pci_dev_16_2_fsb_err_regs) { ++ /* At least one device was not found */ ++ i7300_printk(KERN_ERR, ++ "'system address,Process Bus' device not found:" ++ "vendor 0x%x device 0x%x ERR funcs (broken BIOS?)\n", ++ PCI_VENDOR_ID_INTEL, ++ PCI_DEVICE_ID_INTEL_I7300_MCH_ERR); ++ goto error; ++ } ++ + debugf1("System Address, processor bus- PCI Bus ID: %s %x:%x\n", + pci_name(pvt->pci_dev_16_0_fsb_ctlr), + pvt->pci_dev_16_0_fsb_ctlr->vendor, +diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c +index 479011004a11..9bdc3b8597a4 100644 +--- a/drivers/input/mouse/elantech.c ++++ b/drivers/input/mouse/elantech.c +@@ -486,6 +486,7 @@ static void elantech_input_sync_v4(struct psmouse *psmouse) + unsigned char *packet = psmouse->packet; + + input_report_key(dev, BTN_LEFT, packet[0] & 0x01); ++ input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); + input_mt_report_pointer_emulation(dev, true); + input_sync(dev); + } +@@ -954,6 +955,44 @@ static int elantech_get_resolution_v4(struct psmouse *psmouse, + } + + /* ++ * Advertise INPUT_PROP_BUTTONPAD for clickpads. The testing of bit 12 in ++ * fw_version for this is based on the following fw_version & caps table: ++ * ++ * Laptop-model: fw_version: caps: buttons: ++ * Acer S3 0x461f00 10, 13, 0e clickpad ++ * Acer S7-392 0x581f01 50, 17, 0d clickpad ++ * Acer V5-131 0x461f02 01, 16, 0c clickpad ++ * Acer V5-551 0x461f00 ? clickpad ++ * Asus K53SV 0x450f01 78, 15, 0c 2 hw buttons ++ * Asus G46VW 0x460f02 00, 18, 0c 2 hw buttons ++ * Asus G750JX 0x360f00 00, 16, 0c 2 hw buttons ++ * Asus UX31 0x361f00 20, 15, 0e clickpad ++ * Asus UX32VD 0x361f02 00, 15, 0e clickpad ++ * Avatar AVIU-145A2 0x361f00 ? clickpad ++ * Gigabyte U2442 0x450f01 58, 17, 0c 2 hw buttons ++ * Lenovo L430 0x350f02 b9, 15, 0c 2 hw buttons (*) ++ * Samsung NF210 0x150b00 78, 14, 0a 2 hw buttons ++ * Samsung NP770Z5E 0x575f01 10, 15, 0f clickpad ++ * Samsung NP700Z5B 0x361f06 21, 15, 0f clickpad ++ * Samsung NP900X3E-A02 0x575f03 ? clickpad ++ * Samsung NP-QX410 0x851b00 19, 14, 0c clickpad ++ * Samsung RC512 0x450f00 08, 15, 0c 2 hw buttons ++ * Samsung RF710 0x450f00 ? 2 hw buttons ++ * System76 Pangolin 0x250f01 ? 2 hw buttons ++ * (*) + 3 trackpoint buttons ++ */ ++static void elantech_set_buttonpad_prop(struct psmouse *psmouse) ++{ ++ struct input_dev *dev = psmouse->dev; ++ struct elantech_data *etd = psmouse->private; ++ ++ if (etd->fw_version & 0x001000) { ++ __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); ++ __clear_bit(BTN_RIGHT, dev->keybit); ++ } ++} ++ ++/* + * Set the appropriate event bits for the input subsystem + */ + static int elantech_set_input_params(struct psmouse *psmouse) +@@ -996,6 +1035,8 @@ static int elantech_set_input_params(struct psmouse *psmouse) + __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); + /* fall through */ + case 3: ++ if (etd->hw_version == 3) ++ elantech_set_buttonpad_prop(psmouse); + input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0); + input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0); + if (etd->reports_pressure) { +@@ -1017,9 +1058,7 @@ static int elantech_set_input_params(struct psmouse *psmouse) + */ + psmouse_warn(psmouse, "couldn't query resolution data.\n"); + } +- /* v4 is clickpad, with only one button. */ +- __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); +- __clear_bit(BTN_RIGHT, dev->keybit); ++ elantech_set_buttonpad_prop(psmouse); + __set_bit(BTN_TOOL_QUADTAP, dev->keybit); + /* For X to recognize me as touchpad. */ + input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0); +diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +index 91bad2f23842..ba38ace80a49 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c ++++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +@@ -825,14 +825,15 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) + trace_idx = 1; + #endif + ++ /* map the remaining (adjusted) nocopy/dup fragments */ + for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { +- if (!cmd->len[i]) ++ if (!cmdlen[i]) + continue; + if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) + continue; + phys_addr = dma_map_single(trans->dev, +- (void *)cmd->data[i], +- cmd->len[i], DMA_BIDIRECTIONAL); ++ (void *)cmddata[i], ++ cmdlen[i], DMA_BIDIRECTIONAL); + if (dma_mapping_error(trans->dev, phys_addr)) { + iwlagn_unmap_tfd(trans, out_meta, + &txq->tfds[q->write_ptr], +diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c +index a08a6f0e4dd1..29338190ee27 100644 +--- a/drivers/net/wireless/p54/txrx.c ++++ b/drivers/net/wireless/p54/txrx.c +@@ -583,7 +583,7 @@ static void p54_rx_stats(struct p54_common *priv, struct sk_buff *skb) + chan = priv->curchan; + if (chan) { + struct survey_info *survey = &priv->survey[chan->hw_value]; +- survey->noise = clamp_t(s8, priv->noise, -128, 127); ++ survey->noise = clamp(priv->noise, -128, 127); + survey->channel_time = priv->survey_raw.active; + survey->channel_time_tx = priv->survey_raw.tx; + survey->channel_time_busy = priv->survey_raw.tx + +diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c +index 8b1c27f93025..496764b60a3b 100644 +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -109,6 +109,11 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) + xhci_dbg(xhci, "QUIRK: Resetting on resume\n"); + xhci->quirks |= XHCI_TRUST_TX_LENGTH; + } ++ if (pdev->vendor == PCI_VENDOR_ID_RENESAS && ++ pdev->device == 0x0015 && ++ pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG && ++ pdev->subsystem_device == 0xc0cd) ++ xhci->quirks |= XHCI_RESET_ON_RESUME; + if (pdev->vendor == PCI_VENDOR_ID_VIA) + xhci->quirks |= XHCI_RESET_ON_RESUME; + } +diff --git a/ipc/msg.c b/ipc/msg.c +index 7385de25788a..25f1a6139584 100644 +--- a/ipc/msg.c ++++ b/ipc/msg.c +@@ -296,7 +296,9 @@ static void freeque(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp) + } + atomic_sub(msq->q_cbytes, &ns->msg_bytes); + security_msg_queue_free(msq); ++ ipc_lock_by_ptr(&msq->q_perm); + ipc_rcu_putref(msq); ++ ipc_unlock(&msq->q_perm); + } + + /* +diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c +index d8f031a762ae..835d81b0934e 100644 +--- a/net/ceph/osd_client.c ++++ b/net/ceph/osd_client.c +@@ -1269,14 +1269,17 @@ static void reset_changed_osds(struct ceph_osd_client *osdc) + * + * Caller should hold map_sem for read. + */ +-static void kick_requests(struct ceph_osd_client *osdc, int force_resend) ++static void kick_requests(struct ceph_osd_client *osdc, bool force_resend, ++ bool force_resend_writes) + { + struct ceph_osd_request *req, *nreq; + struct rb_node *p; + int needmap = 0; + int err; ++ bool force_resend_req; + +- dout("kick_requests %s\n", force_resend ? " (force resend)" : ""); ++ dout("kick_requests %s %s\n", force_resend ? " (force resend)" : "", ++ force_resend_writes ? " (force resend writes)" : ""); + mutex_lock(&osdc->request_mutex); + for (p = rb_first(&osdc->requests); p; ) { + req = rb_entry(p, struct ceph_osd_request, r_node); +@@ -1299,7 +1302,10 @@ static void kick_requests(struct ceph_osd_client *osdc, int force_resend) + continue; + } + +- err = __map_request(osdc, req, force_resend); ++ force_resend_req = force_resend || ++ (force_resend_writes && ++ req->r_flags & CEPH_OSD_FLAG_WRITE); ++ err = __map_request(osdc, req, force_resend_req); + if (err < 0) + continue; /* error */ + if (req->r_osd == NULL) { +@@ -1319,7 +1325,8 @@ static void kick_requests(struct ceph_osd_client *osdc, int force_resend) + r_linger_item) { + dout("linger req=%p req->r_osd=%p\n", req, req->r_osd); + +- err = __map_request(osdc, req, force_resend); ++ err = __map_request(osdc, req, ++ force_resend || force_resend_writes); + dout("__map_request returned %d\n", err); + if (err == 0) + continue; /* no change and no osd was specified */ +@@ -1361,6 +1368,7 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg) + struct ceph_osdmap *newmap = NULL, *oldmap; + int err; + struct ceph_fsid fsid; ++ bool was_full; + + dout("handle_map have %u\n", osdc->osdmap ? osdc->osdmap->epoch : 0); + p = msg->front.iov_base; +@@ -1374,6 +1382,8 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg) + + down_write(&osdc->map_sem); + ++ was_full = ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_FULL); ++ + /* incremental maps */ + ceph_decode_32_safe(&p, end, nr_maps, bad); + dout(" %d inc maps\n", nr_maps); +@@ -1398,7 +1408,10 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg) + ceph_osdmap_destroy(osdc->osdmap); + osdc->osdmap = newmap; + } +- kick_requests(osdc, 0); ++ was_full = was_full || ++ ceph_osdmap_flag(osdc->osdmap, ++ CEPH_OSDMAP_FULL); ++ kick_requests(osdc, 0, was_full); + } else { + dout("ignoring incremental map %u len %d\n", + epoch, maplen); +@@ -1441,7 +1454,10 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg) + skipped_map = 1; + ceph_osdmap_destroy(oldmap); + } +- kick_requests(osdc, skipped_map); ++ was_full = was_full || ++ ceph_osdmap_flag(osdc->osdmap, ++ CEPH_OSDMAP_FULL); ++ kick_requests(osdc, skipped_map, was_full); + } + p += maplen; + nr_maps--; +diff --git a/scripts/package/builddeb b/scripts/package/builddeb +index eee5f8ed2493..ed7ccdcd3e6e 100644 +--- a/scripts/package/builddeb ++++ b/scripts/package/builddeb +@@ -62,7 +62,7 @@ create_package() { + fi + + # Create the package +- dpkg-gencontrol -isp $forcearch -p$pname -P"$pdir" ++ dpkg-gencontrol -isp $forcearch -Vkernel:debarch="${debarch:-$(dpkg --print-architecture)}" -p$pname -P"$pdir" + dpkg --build "$pdir" .. + } + +@@ -252,15 +252,14 @@ mkdir -p "$destdir" + (cd $objtree; tar -c -f - -T "$objtree/debian/hdrobjfiles") | (cd $destdir; tar -xf -) + ln -sf "/usr/src/linux-headers-$version" "$kernel_headers_dir/lib/modules/$version/build" + rm -f "$objtree/debian/hdrsrcfiles" "$objtree/debian/hdrobjfiles" +-arch=$(dpkg --print-architecture) + + cat <> debian/control + + Package: $kernel_headers_packagename + Provides: linux-headers, linux-headers-2.6 +-Architecture: $arch +-Description: Linux kernel headers for $KERNELRELEASE on $arch +- This package provides kernel header files for $KERNELRELEASE on $arch ++Architecture: any ++Description: Linux kernel headers for $KERNELRELEASE on \${kernel:debarch} ++ This package provides kernel header files for $KERNELRELEASE on \${kernel:debarch} + . + This is useful for people who need to build external modules + EOF +diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c +index 7895983862b2..1edb2e822074 100644 +--- a/sound/core/compress_offload.c ++++ b/sound/core/compress_offload.c +@@ -133,7 +133,7 @@ static int snd_compr_open(struct inode *inode, struct file *f) + kfree(data); + } + snd_card_unref(compr->card); +- return 0; ++ return ret; + } + + static int snd_compr_free(struct inode *inode, struct file *f) diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.85-86.patch b/patch/kernel/sun8i-default/0001-patch-3.4.85-86.patch new file mode 100644 index 000000000..9b87b18c9 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.85-86.patch @@ -0,0 +1,2510 @@ +diff --git a/Makefile b/Makefile +index 66ae2984a38c..4958e39a9d9c 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 85 ++SUBLEVEL = 86 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h +index b9676ae37ada..ddaf130e9000 100644 +--- a/arch/x86/include/asm/topology.h ++++ b/arch/x86/include/asm/topology.h +@@ -157,9 +157,10 @@ static inline void setup_node_to_cpumask_map(void) { } + + extern const struct cpumask *cpu_coregroup_mask(int cpu); + +-#ifdef ENABLE_TOPO_DEFINES + #define topology_physical_package_id(cpu) (cpu_data(cpu).phys_proc_id) + #define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id) ++ ++#ifdef ENABLE_TOPO_DEFINES + #define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu)) + #define topology_thread_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu)) + +diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c +index e2c2e1e2bd6f..c1f7e9b65088 100644 +--- a/drivers/input/mouse/synaptics.c ++++ b/drivers/input/mouse/synaptics.c +@@ -232,11 +232,22 @@ static int synaptics_identify(struct psmouse *psmouse) + * Read touchpad resolution and maximum reported coordinates + * Resolution is left zero if touchpad does not support the query + */ ++ ++static const int *quirk_min_max; ++ + static int synaptics_resolution(struct psmouse *psmouse) + { + struct synaptics_data *priv = psmouse->private; + unsigned char resp[3]; + ++ if (quirk_min_max) { ++ priv->x_min = quirk_min_max[0]; ++ priv->x_max = quirk_min_max[1]; ++ priv->y_min = quirk_min_max[2]; ++ priv->y_max = quirk_min_max[3]; ++ return 0; ++ } ++ + if (SYN_ID_MAJOR(priv->identity) < 4) + return 0; + +@@ -1412,10 +1423,54 @@ static const struct dmi_system_id __initconst olpc_dmi_table[] = { + { } + }; + ++static const struct dmi_system_id min_max_dmi_table[] __initconst = { ++#if defined(CONFIG_DMI) ++ { ++ /* Lenovo ThinkPad Helix */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Helix"), ++ }, ++ .driver_data = (int []){1024, 5052, 2258, 4832}, ++ }, ++ { ++ /* Lenovo ThinkPad X240 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X240"), ++ }, ++ .driver_data = (int []){1232, 5710, 1156, 4696}, ++ }, ++ { ++ /* Lenovo ThinkPad T440s */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T440"), ++ }, ++ .driver_data = (int []){1024, 5112, 2024, 4832}, ++ }, ++ { ++ /* Lenovo ThinkPad T540p */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T540"), ++ }, ++ .driver_data = (int []){1024, 5056, 2058, 4832}, ++ }, ++#endif ++ { } ++}; ++ + void __init synaptics_module_init(void) + { ++ const struct dmi_system_id *min_max_dmi; ++ + impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table); + broken_olpc_ec = dmi_check_system(olpc_dmi_table); ++ ++ min_max_dmi = dmi_first_match(min_max_dmi_table); ++ if (min_max_dmi) ++ quirk_min_max = min_max_dmi->driver_data; + } + + static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) +diff --git a/drivers/staging/speakup/i18n.c b/drivers/staging/speakup/i18n.c +index c2119433f333..7656014c7bdd 100644 +--- a/drivers/staging/speakup/i18n.c ++++ b/drivers/staging/speakup/i18n.c +@@ -390,7 +390,7 @@ static struct msg_group_t all_groups[] = { + + static const int num_groups = sizeof(all_groups) / sizeof(struct msg_group_t); + +-char *msg_get(enum msg_index_t index) ++char *spk_msg_get(enum msg_index_t index) + { + char *ch; + +@@ -540,7 +540,7 @@ static int fmt_validate(char *template, char *user) + * -EINVAL - Invalid format specifiers in formatted message or illegal index. + * -ENOMEM - Unable to allocate memory. + */ +-ssize_t msg_set(enum msg_index_t index, char *text, size_t length) ++ssize_t spk_msg_set(enum msg_index_t index, char *text, size_t length) + { + int rc = 0; + char *newstr = NULL; +@@ -575,7 +575,7 @@ ssize_t msg_set(enum msg_index_t index, char *text, size_t length) + * Find a message group, given its name. Return a pointer to the structure + * if found, or NULL otherwise. + */ +-struct msg_group_t *find_msg_group(const char *group_name) ++struct msg_group_t *spk_find_msg_group(const char *group_name) + { + struct msg_group_t *group = NULL; + int i; +@@ -589,7 +589,7 @@ struct msg_group_t *find_msg_group(const char *group_name) + return group; + } + +-void reset_msg_group(struct msg_group_t *group) ++void spk_reset_msg_group(struct msg_group_t *group) + { + unsigned long flags; + enum msg_index_t i; +@@ -605,14 +605,14 @@ void reset_msg_group(struct msg_group_t *group) + } + + /* Called at initialization time, to establish default messages. */ +-void initialize_msgs(void) ++void spk_initialize_msgs(void) + { + memcpy(speakup_msgs, speakup_default_msgs, + sizeof(speakup_default_msgs)); + } + + /* Free user-supplied strings when module is unloaded: */ +-void free_user_msgs(void) ++void spk_free_user_msgs(void) + { + enum msg_index_t index; + unsigned long flags; +diff --git a/drivers/staging/speakup/i18n.h b/drivers/staging/speakup/i18n.h +index 65caa8010776..dd338f4218de 100644 +--- a/drivers/staging/speakup/i18n.h ++++ b/drivers/staging/speakup/i18n.h +@@ -218,11 +218,11 @@ struct msg_group_t { + enum msg_index_t end; + }; + +-extern char *msg_get(enum msg_index_t index); +-extern ssize_t msg_set(enum msg_index_t index, char *text, size_t length); +-extern struct msg_group_t *find_msg_group(const char *group_name); +-extern void reset_msg_group(struct msg_group_t *group); +-extern void initialize_msgs(void); +-extern void free_user_msgs(void); ++extern char *spk_msg_get(enum msg_index_t index); ++extern ssize_t spk_msg_set(enum msg_index_t index, char *text, size_t length); ++extern struct msg_group_t *spk_find_msg_group(const char *group_name); ++extern void spk_reset_msg_group(struct msg_group_t *group); ++extern void spk_initialize_msgs(void); ++extern void spk_free_user_msgs(void); + + #endif +diff --git a/drivers/staging/speakup/keyhelp.c b/drivers/staging/speakup/keyhelp.c +index 170f38815ffd..4c584ecbd1fa 100644 +--- a/drivers/staging/speakup/keyhelp.c ++++ b/drivers/staging/speakup/keyhelp.c +@@ -115,10 +115,10 @@ static void say_key(int key) + key &= 0xff; + for (i = 0; i < 6; i++) { + if (state & masks[i]) +- synth_printf(" %s", msg_get(MSG_STATES_START + i)); ++ synth_printf(" %s", spk_msg_get(MSG_STATES_START + i)); + } + if ((key > 0) && (key <= num_key_names)) +- synth_printf(" %s\n", msg_get(MSG_KEYNAMES_START + (key - 1))); ++ synth_printf(" %s\n", spk_msg_get(MSG_KEYNAMES_START + (key - 1))); + } + + static int help_init(void) +@@ -126,9 +126,9 @@ static int help_init(void) + char start = SPACE; + int i; + int num_funcs = MSG_FUNCNAMES_END - MSG_FUNCNAMES_START + 1; +-state_tbl = our_keys[0]+SHIFT_TBL_SIZE+2; ++state_tbl = spk_our_keys[0]+SHIFT_TBL_SIZE+2; + for (i = 0; i < num_funcs; i++) { +- char *cur_funcname = msg_get(MSG_FUNCNAMES_START + i); ++ char *cur_funcname = spk_msg_get(MSG_FUNCNAMES_START + i); + if (start == *cur_funcname) + continue; + start = *cur_funcname; +@@ -137,7 +137,7 @@ state_tbl = our_keys[0]+SHIFT_TBL_SIZE+2; + return 0; + } + +-int handle_help(struct vc_data *vc, u_char type, u_char ch, u_short key) ++int spk_handle_help(struct vc_data *vc, u_char type, u_char ch, u_short key) + { + int i, n; + char *name; +@@ -147,15 +147,15 @@ int handle_help(struct vc_data *vc, u_char type, u_char ch, u_short key) + help_init(); + if (type == KT_LATIN) { + if (ch == SPACE) { +- special_handler = NULL; +- synth_printf("%s\n", msg_get(MSG_LEAVING_HELP)); ++ spk_special_handler = NULL; ++ synth_printf("%s\n", spk_msg_get(MSG_LEAVING_HELP)); + return 1; + } + ch |= 32; /* lower case */ + if (ch < 'a' || ch > 'z') + return -1; + if (letter_offsets[ch-'a'] == -1) { +- synth_printf(msg_get(MSG_NO_COMMAND), ch); ++ synth_printf(spk_msg_get(MSG_NO_COMMAND), ch); + synth_printf("\n"); + return 1; + } +@@ -169,47 +169,47 @@ int handle_help(struct vc_data *vc, u_char type, u_char ch, u_short key) + cur_item--; + else + return -1; +- } else if (type == KT_SPKUP && ch == SPEAKUP_HELP && !special_handler) { +- special_handler = handle_help; +- synth_printf("%s\n", msg_get(MSG_HELP_INFO)); ++ } else if (type == KT_SPKUP && ch == SPEAKUP_HELP && !spk_special_handler) { ++ spk_special_handler = spk_handle_help; ++ synth_printf("%s\n", spk_msg_get(MSG_HELP_INFO)); + build_key_data(); /* rebuild each time in case new mapping */ + return 1; + } else { + name = NULL; + if ((type != KT_SPKUP) && (key > 0) && (key <= num_key_names)) { + synth_printf("%s\n", +- msg_get(MSG_KEYNAMES_START + key-1)); ++ spk_msg_get(MSG_KEYNAMES_START + key-1)); + return 1; + } + for (i = 0; funcvals[i] != 0 && !name; i++) { + if (ch == funcvals[i]) +- name = msg_get(MSG_FUNCNAMES_START + i); ++ name = spk_msg_get(MSG_FUNCNAMES_START + i); + } + if (!name) + return -1; +- kp = our_keys[key]+1; ++ kp = spk_our_keys[key]+1; + for (i = 0; i < nstates; i++) { + if (ch == kp[i]) + break; + } + key += (state_tbl[i] << 8); + say_key(key); +- synth_printf(msg_get(MSG_KEYDESC), name); ++ synth_printf(spk_msg_get(MSG_KEYDESC), name); + synth_printf("\n"); + return 1; + } +- name = msg_get(MSG_FUNCNAMES_START + cur_item); ++ name = spk_msg_get(MSG_FUNCNAMES_START + cur_item); + func = funcvals[cur_item]; + synth_printf("%s", name); + if (key_offsets[func] == 0) { +- synth_printf(" %s\n", msg_get(MSG_IS_UNASSIGNED)); ++ synth_printf(" %s\n", spk_msg_get(MSG_IS_UNASSIGNED)); + return 1; + } + p_keys = key_data + key_offsets[func]; + for (n = 0; p_keys[n]; n++) { + val = p_keys[n]; + if (n > 0) +- synth_printf("%s ", msg_get(MSG_DISJUNCTION)); ++ synth_printf("%s ", spk_msg_get(MSG_DISJUNCTION)); + say_key(val); + } + return 1; +diff --git a/drivers/staging/speakup/kobjects.c b/drivers/staging/speakup/kobjects.c +index 2093896c546b..86387f48b30c 100644 +--- a/drivers/staging/speakup/kobjects.c ++++ b/drivers/staging/speakup/kobjects.c +@@ -41,7 +41,7 @@ static ssize_t chars_chartab_show(struct kobject *kobj, + break; + if (strcmp("characters", attr->attr.name) == 0) { + len = scnprintf(buf_pointer, bufsize, "%d\t%s\n", +- i, characters[i]); ++ i, spk_characters[i]); + } else { /* show chartab entry */ + if (IS_TYPE(i, B_CTL)) + cp = "B_CTL"; +@@ -185,12 +185,12 @@ static ssize_t chars_chartab_store(struct kobject *kobj, + outptr[desc_length] = '\0'; + + if (do_characters) { +- if (characters[index] != default_chars[index]) +- kfree(characters[index]); +- characters[index] = desc; ++ if (spk_characters[index] != spk_default_chars[index]) ++ kfree(spk_characters[index]); ++ spk_characters[index] = desc; + used++; + } else { +- charclass = chartab_get_value(keyword); ++ charclass = spk_chartab_get_value(keyword); + if (charclass == 0) { + rejected++; + cp = linefeed + 1; +@@ -206,9 +206,9 @@ static ssize_t chars_chartab_store(struct kobject *kobj, + + if (reset) { + if (do_characters) +- reset_default_chars(); ++ spk_reset_default_chars(); + else +- reset_default_chartab(); ++ spk_reset_default_chartab(); + } + + spk_unlock(flags); +@@ -232,7 +232,7 @@ static ssize_t keymap_show(struct kobject *kobj, struct kobj_attribute *attr, + u_char ch; + unsigned long flags; + spk_lock(flags); +- cp1 = key_buf + SHIFT_TBL_SIZE; ++ cp1 = spk_key_buf + SHIFT_TBL_SIZE; + num_keys = (int)(*cp1); + nstates = (int)cp1[1]; + cp += sprintf(cp, "%d, %d, %d,\n", KEY_MAP_VER, num_keys, nstates); +@@ -271,7 +271,7 @@ static ssize_t keymap_store(struct kobject *kobj, struct kobj_attribute *attr, + return -ENOMEM; + } + if (strchr("dDrR", *in_buff)) { +- set_key_info(key_defaults, key_buf); ++ spk_set_key_info(spk_key_defaults, spk_key_buf); + pr_info("keymap set to default values\n"); + kfree(in_buff); + spk_unlock(flags); +@@ -282,14 +282,14 @@ static ssize_t keymap_store(struct kobject *kobj, struct kobj_attribute *attr, + cp = in_buff; + cp1 = (u_char *)in_buff; + for (i = 0; i < 3; i++) { +- cp = s2uchar(cp, cp1); ++ cp = spk_s2uchar(cp, cp1); + cp1++; + } + i = (int)cp1[-2]+1; + i *= (int)cp1[-1]+1; + i += 2; /* 0 and last map ver */ + if (cp1[-3] != KEY_MAP_VER || cp1[-1] > 10 || +- i+SHIFT_TBL_SIZE+4 >= sizeof(key_buf)) { ++ i+SHIFT_TBL_SIZE+4 >= sizeof(spk_key_buf)) { + pr_warn("i %d %d %d %d\n", i, + (int)cp1[-3], (int)cp1[-2], (int)cp1[-1]); + kfree(in_buff); +@@ -297,7 +297,7 @@ static ssize_t keymap_store(struct kobject *kobj, struct kobj_attribute *attr, + return -EINVAL; + } + while (--i >= 0) { +- cp = s2uchar(cp, cp1); ++ cp = spk_s2uchar(cp, cp1); + cp1++; + if (!(*cp)) + break; +@@ -307,8 +307,8 @@ static ssize_t keymap_store(struct kobject *kobj, struct kobj_attribute *attr, + pr_warn("end %d %d %d %d\n", i, + (int)cp1[-3], (int)cp1[-2], (int)cp1[-1]); + } else { +- if (set_key_info(in_buff, key_buf)) { +- set_key_info(key_defaults, key_buf); ++ if (spk_set_key_info(in_buff, spk_key_buf)) { ++ spk_set_key_info(spk_key_defaults, spk_key_buf); + ret = -EINVAL; + pr_warn("set key failed\n"); + } +@@ -343,7 +343,7 @@ static ssize_t silent_store(struct kobject *kobj, struct kobj_attribute *attr, + spk_lock(flags); + if (ch&2) { + shut = 1; +- do_flush(); ++ spk_do_flush(); + } else { + shut = 0; + } +@@ -388,7 +388,7 @@ static ssize_t synth_store(struct kobject *kobj, struct kobj_attribute *attr, + if (new_synth_name[len - 1] == '\n') + len--; + new_synth_name[len] = '\0'; +- strlwr(new_synth_name); ++ spk_strlwr(new_synth_name); + if ((synth != NULL) && (!strcmp(new_synth_name, synth->name))) { + pr_warn("%s already in use\n", new_synth_name); + } else if (synth_init(new_synth_name) != 0) { +@@ -417,7 +417,7 @@ static ssize_t synth_direct_store(struct kobject *kobj, + bytes = min_t(size_t, len, 250); + strncpy(tmp, ptr, bytes); + tmp[bytes] = '\0'; +- xlate(tmp); ++ spk_xlate(tmp); + synth_printf("%s", tmp); + ptr += bytes; + len -= bytes; +@@ -455,14 +455,14 @@ static ssize_t punc_show(struct kobject *kobj, struct kobj_attribute *attr, + short mask; + unsigned long flags; + +- p_header = var_header_by_name(attr->attr.name); ++ p_header = spk_var_header_by_name(attr->attr.name); + if (p_header == NULL) { + pr_warn("p_header is null, attr->attr.name is %s\n", + attr->attr.name); + return -EINVAL; + } + +- var = get_punc_var(p_header->var_id); ++ var = spk_get_punc_var(p_header->var_id); + if (var == NULL) { + pr_warn("var is null, p_header->var_id is %i\n", + p_header->var_id); +@@ -470,7 +470,7 @@ static ssize_t punc_show(struct kobject *kobj, struct kobj_attribute *attr, + } + + spk_lock(flags); +- pb = (struct st_bits_data *) &punc_info[var->value]; ++ pb = (struct st_bits_data *) &spk_punc_info[var->value]; + mask = pb->mask; + for (i = 33; i < 128; i++) { + if (!(spk_chartab[i]&mask)) +@@ -497,14 +497,14 @@ static ssize_t punc_store(struct kobject *kobj, struct kobj_attribute *attr, + if (x < 1 || x > 99) + return -EINVAL; + +- p_header = var_header_by_name(attr->attr.name); ++ p_header = spk_var_header_by_name(attr->attr.name); + if (p_header == NULL) { + pr_warn("p_header is null, attr->attr.name is %s\n", + attr->attr.name); + return -EINVAL; + } + +- var = get_punc_var(p_header->var_id); ++ var = spk_get_punc_var(p_header->var_id); + if (var == NULL) { + pr_warn("var is null, p_header->var_id is %i\n", + p_header->var_id); +@@ -520,9 +520,9 @@ static ssize_t punc_store(struct kobject *kobj, struct kobj_attribute *attr, + spk_lock(flags); + + if (*punc_buf == 'd' || *punc_buf == 'r') +- x = set_mask_bits(0, var->value, 3); ++ x = spk_set_mask_bits(0, var->value, 3); + else +- x = set_mask_bits(punc_buf, var->value, 3); ++ x = spk_set_mask_bits(punc_buf, var->value, 3); + + spk_unlock(flags); + return count; +@@ -542,7 +542,7 @@ ssize_t spk_var_show(struct kobject *kobj, struct kobj_attribute *attr, + char ch; + unsigned long flags; + +- param = var_header_by_name(attr->attr.name); ++ param = spk_var_header_by_name(attr->attr.name); + if (param == NULL) + return -EINVAL; + +@@ -599,13 +599,13 @@ ssize_t spk_var_store(struct kobject *kobj, struct kobj_attribute *attr, + int value; + unsigned long flags; + +- param = var_header_by_name(attr->attr.name); ++ param = spk_var_header_by_name(attr->attr.name); + if (param == NULL) + return -EINVAL; + if (param->data == NULL) + return 0; + ret = 0; +- cp = xlate((char *) buf); ++ cp = spk_xlate((char *) buf); + + spk_lock(flags); + switch (param->var_type) { +@@ -618,7 +618,7 @@ ssize_t spk_var_store(struct kobject *kobj, struct kobj_attribute *attr, + else + len = E_SET; + speakup_s2i(cp, &value); +- ret = set_num_var(value, param, len); ++ ret = spk_set_num_var(value, param, len); + if (ret == E_RANGE) { + var_data = param->data; + pr_warn("value for %s out of range, expect %d to %d\n", +@@ -636,7 +636,7 @@ ssize_t spk_var_store(struct kobject *kobj, struct kobj_attribute *attr, + } + cp = (char *) buf; + cp[len] = '\0'; +- ret = set_string_var(buf, param, len); ++ ret = spk_set_string_var(buf, param, len); + if (ret == E_TOOLONG) + pr_warn("value too long for %s\n", + attr->attr.name); +@@ -652,19 +652,19 @@ ssize_t spk_var_store(struct kobject *kobj, struct kobj_attribute *attr, + */ + if (strcmp(attr->attr.name, "voice") == 0) { + if (synth && synth->default_pitch) { +- param = var_header_by_name("pitch"); ++ param = spk_var_header_by_name("pitch"); + if (param) { +- set_num_var(synth->default_pitch[value], param, ++ spk_set_num_var(synth->default_pitch[value], param, + E_NEW_DEFAULT); +- set_num_var(0, param, E_DEFAULT); ++ spk_set_num_var(0, param, E_DEFAULT); + } + } + if (synth && synth->default_vol) { +- param = var_header_by_name("vol"); ++ param = spk_var_header_by_name("vol"); + if (param) { +- set_num_var(synth->default_vol[value], param, ++ spk_set_num_var(synth->default_vol[value], param, + E_NEW_DEFAULT); +- set_num_var(0, param, E_DEFAULT); ++ spk_set_num_var(0, param, E_DEFAULT); + } + } + } +@@ -694,7 +694,7 @@ static ssize_t message_show_helper(char *buf, enum msg_index_t first, + if (bufsize <= 1) + break; + printed = scnprintf(buf_pointer, bufsize, "%d\t%s\n", +- index, msg_get(cursor)); ++ index, spk_msg_get(cursor)); + buf_pointer += printed; + bufsize -= printed; + } +@@ -788,7 +788,7 @@ static ssize_t message_store_helper(const char *buf, size_t count, + continue; + } + +- msg_stored = msg_set(curmessage, temp, desc_length); ++ msg_stored = spk_msg_set(curmessage, temp, desc_length); + if (msg_stored < 0) { + retval = msg_stored; + if (msg_stored == -ENOMEM) +@@ -802,7 +802,7 @@ static ssize_t message_store_helper(const char *buf, size_t count, + } + + if (reset) +- reset_msg_group(group); ++ spk_reset_msg_group(group); + + report_msg_status(reset, received, used, rejected, group->name); + return retval; +@@ -812,7 +812,7 @@ static ssize_t message_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) + { + ssize_t retval = 0; +- struct msg_group_t *group = find_msg_group(attr->attr.name); ++ struct msg_group_t *group = spk_find_msg_group(attr->attr.name); + unsigned long flags; + + BUG_ON(!group); +@@ -826,7 +826,7 @@ static ssize_t message_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) + { + ssize_t retval = 0; +- struct msg_group_t *group = find_msg_group(attr->attr.name); ++ struct msg_group_t *group = spk_find_msg_group(attr->attr.name); + + BUG_ON(!group); + retval = message_store_helper(buf, count, group); +diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c +index 40e2488b9679..463d125ee77b 100644 +--- a/drivers/staging/speakup/main.c ++++ b/drivers/staging/speakup/main.c +@@ -65,23 +65,23 @@ MODULE_VERSION(SPEAKUP_VERSION); + + char *synth_name; + module_param_named(synth, synth_name, charp, S_IRUGO); +-module_param_named(quiet, quiet_boot, bool, S_IRUGO); ++module_param_named(quiet, spk_quiet_boot, bool, S_IRUGO); + + MODULE_PARM_DESC(synth, "Synth to start if speakup is built in."); + MODULE_PARM_DESC(quiet, "Do not announce when the synthesizer is found."); + +-special_func special_handler; ++special_func spk_special_handler; + +-short pitch_shift, synth_flags; ++short spk_pitch_shift, synth_flags; + static char buf[256]; +-int attrib_bleep, bleeps, bleep_time = 10; +-int no_intr, spell_delay; +-int key_echo, say_word_ctl; +-int say_ctrl, bell_pos; +-short punc_mask; +-int punc_level, reading_punc; +-char str_caps_start[MAXVARLEN + 1] = "\0", str_caps_stop[MAXVARLEN + 1] = "\0"; +-const struct st_bits_data punc_info[] = { ++int spk_attrib_bleep, spk_bleeps, spk_bleep_time = 10; ++int spk_no_intr, spk_spell_delay; ++int spk_key_echo, spk_say_word_ctl; ++int spk_say_ctrl, spk_bell_pos; ++short spk_punc_mask; ++int spk_punc_level, spk_reading_punc; ++char spk_str_caps_start[MAXVARLEN + 1] = "\0", spk_str_caps_stop[MAXVARLEN + 1] = "\0"; ++const struct st_bits_data spk_punc_info[] = { + {"none", "", 0}, + {"some", "/$%&@", SOME}, + {"most", "$%&#()=+*/@^<>|\\", MOST}, +@@ -95,9 +95,9 @@ const struct st_bits_data punc_info[] = { + + static char mark_cut_flag; + #define MAX_KEY 160 +-u_char *our_keys[MAX_KEY], *shift_table; +-u_char key_buf[600]; +-const u_char key_defaults[] = { ++u_char *spk_our_keys[MAX_KEY], *spk_shift_table; ++u_char spk_key_buf[600]; ++const u_char spk_key_defaults[] = { + #include "speakupmap.h" + }; + +@@ -129,9 +129,9 @@ static char *phonetic[] = { + /* array of 256 char pointers (one for each character description) + * initialized to default_chars and user selectable via + * /proc/speakup/characters */ +-char *characters[256]; ++char *spk_characters[256]; + +-char *default_chars[256] = { ++char *spk_default_chars[256] = { + /*000*/ "null", "^a", "^b", "^c", "^d", "^e", "^f", "^g", + /*008*/ "^h", "^i", "^j", "^k", "^l", "^m", "^n", "^o", + /*016*/ "^p", "^q", "^r", "^s", "^t", "^u", "^v", "^w", +@@ -238,7 +238,7 @@ static u_short default_chartab[256] = { + }; + + struct task_struct *speakup_task; +-struct bleep unprocessed_sound; ++struct bleep spk_unprocessed_sound; + static int spk_keydown; + static u_char spk_lastkey, spk_close_press, keymap_flags; + static u_char last_keycode, this_speakup_key; +@@ -282,13 +282,13 @@ static void bleep(u_short val) + 350, 370, 392, 414, 440, 466, 491, 523, 554, 587, 619, 659 + }; + short freq; +- int time = bleep_time; ++ int time = spk_bleep_time; + freq = vals[val % 12]; + if (val > 11) + freq *= (1 << (val / 12)); +- unprocessed_sound.freq = freq; +- unprocessed_sound.jiffies = msecs_to_jiffies(time); +- unprocessed_sound.active = 1; ++ spk_unprocessed_sound.freq = freq; ++ spk_unprocessed_sound.jiffies = msecs_to_jiffies(time); ++ spk_unprocessed_sound.active = 1; + /* We can only have 1 active sound at a time. */ + } + +@@ -300,7 +300,7 @@ static void speakup_shut_up(struct vc_data *vc) + spk_parked &= 0xfe; + speakup_date(vc); + if (synth != NULL) +- do_flush(); ++ spk_do_flush(); + } + + static void speech_kill(struct vc_data *vc) +@@ -313,9 +313,9 @@ static void speech_kill(struct vc_data *vc) + if (val == 2 || spk_killed) { + /* dead */ + spk_shut_up &= ~0x40; +- synth_printf("%s\n", msg_get(MSG_IAM_ALIVE)); ++ synth_printf("%s\n", spk_msg_get(MSG_IAM_ALIVE)); + } else { +- synth_printf("%s\n", msg_get(MSG_YOU_KILLED_SPEAKUP)); ++ synth_printf("%s\n", spk_msg_get(MSG_YOU_KILLED_SPEAKUP)); + spk_shut_up |= 0x40; + } + } +@@ -324,10 +324,10 @@ static void speakup_off(struct vc_data *vc) + { + if (spk_shut_up & 0x80) { + spk_shut_up &= 0x7f; +- synth_printf("%s\n", msg_get(MSG_HEY_THATS_BETTER)); ++ synth_printf("%s\n", spk_msg_get(MSG_HEY_THATS_BETTER)); + } else { + spk_shut_up |= 0x80; +- synth_printf("%s\n", msg_get(MSG_YOU_TURNED_ME_OFF)); ++ synth_printf("%s\n", spk_msg_get(MSG_YOU_TURNED_ME_OFF)); + } + speakup_date(vc); + } +@@ -336,10 +336,10 @@ static void speakup_parked(struct vc_data *vc) + { + if (spk_parked & 0x80) { + spk_parked = 0; +- synth_printf("%s\n", msg_get(MSG_UNPARKED)); ++ synth_printf("%s\n", spk_msg_get(MSG_UNPARKED)); + } else { + spk_parked |= 0x80; +- synth_printf("%s\n", msg_get(MSG_PARKED)); ++ synth_printf("%s\n", spk_msg_get(MSG_PARKED)); + } + } + +@@ -350,16 +350,16 @@ static void speakup_cut(struct vc_data *vc) + + if (!mark_cut_flag) { + mark_cut_flag = 1; +- xs = (u_short) spk_x; +- ys = (u_short) spk_y; ++ spk_xs = (u_short) spk_x; ++ spk_ys = (u_short) spk_y; + spk_sel_cons = vc; +- synth_printf("%s\n", msg_get(MSG_MARK)); ++ synth_printf("%s\n", spk_msg_get(MSG_MARK)); + return; + } +- xe = (u_short) spk_x; +- ye = (u_short) spk_y; ++ spk_xe = (u_short) spk_x; ++ spk_ye = (u_short) spk_y; + mark_cut_flag = 0; +- synth_printf("%s\n", msg_get(MSG_CUT)); ++ synth_printf("%s\n", spk_msg_get(MSG_CUT)); + + speakup_clear_selection(); + ret = speakup_set_selection(tty); +@@ -383,9 +383,9 @@ static void speakup_paste(struct vc_data *vc) + { + if (mark_cut_flag) { + mark_cut_flag = 0; +- synth_printf("%s\n", msg_get(MSG_MARK_CLEARED)); ++ synth_printf("%s\n", spk_msg_get(MSG_MARK_CLEARED)); + } else { +- synth_printf("%s\n", msg_get(MSG_PASTE)); ++ synth_printf("%s\n", spk_msg_get(MSG_PASTE)); + speakup_paste_selection(tty); + } + } +@@ -395,16 +395,16 @@ static void say_attributes(struct vc_data *vc) + int fg = spk_attr & 0x0f; + int bg = spk_attr >> 4; + if (fg > 8) { +- synth_printf("%s ", msg_get(MSG_BRIGHT)); ++ synth_printf("%s ", spk_msg_get(MSG_BRIGHT)); + fg -= 8; + } +- synth_printf("%s", msg_get(MSG_COLORS_START + fg)); ++ synth_printf("%s", spk_msg_get(MSG_COLORS_START + fg)); + if (bg > 7) { +- synth_printf(" %s ", msg_get(MSG_ON_BLINKING)); ++ synth_printf(" %s ", spk_msg_get(MSG_ON_BLINKING)); + bg -= 8; + } else +- synth_printf(" %s ", msg_get(MSG_ON)); +- synth_printf("%s\n", msg_get(MSG_COLORS_START + bg)); ++ synth_printf(" %s ", spk_msg_get(MSG_ON)); ++ synth_printf("%s\n", spk_msg_get(MSG_COLORS_START + bg)); + } + + enum { +@@ -417,24 +417,24 @@ enum { + + static void announce_edge(struct vc_data *vc, int msg_id) + { +- if (bleeps & 1) ++ if (spk_bleeps & 1) + bleep(spk_y); +- if ((bleeps & 2) && (msg_id < edge_quiet)) +- synth_printf("%s\n", msg_get(MSG_EDGE_MSGS_START + msg_id - 1)); ++ if ((spk_bleeps & 2) && (msg_id < edge_quiet)) ++ synth_printf("%s\n", spk_msg_get(MSG_EDGE_MSGS_START + msg_id - 1)); + } + + static void speak_char(u_char ch) + { +- char *cp = characters[ch]; +- struct var_t *direct = get_var(DIRECT); ++ char *cp = spk_characters[ch]; ++ struct var_t *direct = spk_get_var(DIRECT); + if (direct && direct->u.n.value) { + if (IS_CHAR(ch, B_CAP)) { +- pitch_shift++; +- synth_printf("%s", str_caps_start); ++ spk_pitch_shift++; ++ synth_printf("%s", spk_str_caps_start); + } + synth_printf("%c", ch); + if (IS_CHAR(ch, B_CAP)) +- synth_printf("%s", str_caps_stop); ++ synth_printf("%s", spk_str_caps_stop); + return; + } + if (cp == NULL) { +@@ -443,13 +443,13 @@ static void speak_char(u_char ch) + } + synth_buffer_add(SPACE); + if (IS_CHAR(ch, B_CAP)) { +- pitch_shift++; +- synth_printf("%s", str_caps_start); ++ spk_pitch_shift++; ++ synth_printf("%s", spk_str_caps_start); + synth_printf("%s", cp); +- synth_printf("%s", str_caps_stop); ++ synth_printf("%s", spk_str_caps_stop); + } else { + if (*cp == '^') { +- synth_printf("%s", msg_get(MSG_CTRL)); ++ synth_printf("%s", spk_msg_get(MSG_CTRL)); + cp++; + } + synth_printf("%s", cp); +@@ -479,9 +479,9 @@ static void say_char(struct vc_data *vc) + spk_old_attr = spk_attr; + ch = get_char(vc, (u_short *) spk_pos, &spk_attr); + if (spk_attr != spk_old_attr) { +- if (attrib_bleep & 1) ++ if (spk_attrib_bleep & 1) + bleep(spk_y); +- if (attrib_bleep & 2) ++ if (spk_attrib_bleep & 2) + say_attributes(vc); + } + speak_char(ch & 0xff); +@@ -497,7 +497,7 @@ static void say_phonetic_char(struct vc_data *vc) + synth_printf("%s\n", phonetic[--ch]); + } else { + if (IS_CHAR(ch, B_NUM)) +- synth_printf("%s ", msg_get(MSG_NUMBER)); ++ synth_printf("%s ", spk_msg_get(MSG_NUMBER)); + speak_char(ch); + } + } +@@ -527,8 +527,8 @@ static void say_next_char(struct vc_data *vc) + } + + /* get_word - will first check to see if the character under the +- * reading cursor is a space and if say_word_ctl is true it will +- * return the word space. If say_word_ctl is not set it will check to ++ * reading cursor is a space and if spk_say_word_ctl is true it will ++ * return the word space. If spk_say_word_ctl is not set it will check to + * see if there is a word starting on the next position to the right + * and return that word if it exists. If it does not exist it will + * move left to the beginning of any previous word on the line or the +@@ -544,9 +544,9 @@ static u_long get_word(struct vc_data *vc) + ch = (char)get_char(vc, (u_short *) tmp_pos, &temp); + + /* decided to take out the sayword if on a space (mis-information */ +- if (say_word_ctl && ch == SPACE) { ++ if (spk_say_word_ctl && ch == SPACE) { + *buf = '\0'; +- synth_printf("%s\n", msg_get(MSG_SPACE)); ++ synth_printf("%s\n", spk_msg_get(MSG_SPACE)); + return 0; + } else if ((tmpx < vc->vc_cols - 2) + && (ch == SPACE || ch == 0 || IS_WDLM(ch)) +@@ -582,13 +582,13 @@ static u_long get_word(struct vc_data *vc) + static void say_word(struct vc_data *vc) + { + u_long cnt = get_word(vc); +- u_short saved_punc_mask = punc_mask; ++ u_short saved_punc_mask = spk_punc_mask; + if (cnt == 0) + return; +- punc_mask = PUNC; ++ spk_punc_mask = PUNC; + buf[cnt++] = SPACE; + spkup_write(buf, cnt); +- punc_mask = saved_punc_mask; ++ spk_punc_mask = saved_punc_mask; + } + + static void say_prev_word(struct vc_data *vc) +@@ -686,22 +686,22 @@ static void say_next_word(struct vc_data *vc) + static void spell_word(struct vc_data *vc) + { + static char *delay_str[] = { "", ",", ".", ". .", ". . ." }; +- char *cp = buf, *str_cap = str_caps_stop; +- char *cp1, *last_cap = str_caps_stop; ++ char *cp = buf, *str_cap = spk_str_caps_stop; ++ char *cp1, *last_cap = spk_str_caps_stop; + u_char ch; + if (!get_word(vc)) + return; + while ((ch = (u_char) *cp)) { + if (cp != buf) +- synth_printf(" %s ", delay_str[spell_delay]); ++ synth_printf(" %s ", delay_str[spk_spell_delay]); + if (IS_CHAR(ch, B_CAP)) { +- str_cap = str_caps_start; +- if (*str_caps_stop) +- pitch_shift++; ++ str_cap = spk_str_caps_start; ++ if (*spk_str_caps_stop) ++ spk_pitch_shift++; + else /* synth has no pitch */ +- last_cap = str_caps_stop; ++ last_cap = spk_str_caps_stop; + } else +- str_cap = str_caps_stop; ++ str_cap = spk_str_caps_stop; + if (str_cap != last_cap) { + synth_printf("%s", str_cap); + last_cap = str_cap; +@@ -711,17 +711,17 @@ static void spell_word(struct vc_data *vc) + ch &= 31; + cp1 = phonetic[--ch]; + } else { +- cp1 = characters[ch]; ++ cp1 = spk_characters[ch]; + if (*cp1 == '^') { +- synth_printf("%s", msg_get(MSG_CTRL)); ++ synth_printf("%s", spk_msg_get(MSG_CTRL)); + cp1++; + } + } + synth_printf("%s", cp1); + cp++; + } +- if (str_cap != str_caps_stop) +- synth_printf("%s", str_caps_stop); ++ if (str_cap != spk_str_caps_stop) ++ synth_printf("%s", spk_str_caps_stop); + } + + static int get_line(struct vc_data *vc) +@@ -746,9 +746,9 @@ static void say_line(struct vc_data *vc) + { + int i = get_line(vc); + char *cp; +- u_short saved_punc_mask = punc_mask; ++ u_short saved_punc_mask = spk_punc_mask; + if (i == 0) { +- synth_printf("%s\n", msg_get(MSG_BLANK)); ++ synth_printf("%s\n", spk_msg_get(MSG_BLANK)); + return; + } + buf[i++] = '\n'; +@@ -758,9 +758,9 @@ static void say_line(struct vc_data *vc) + cp++; + synth_printf("%d, ", (cp - buf) + 1); + } +- punc_mask = punc_masks[reading_punc]; ++ spk_punc_mask = spk_punc_masks[spk_reading_punc]; + spkup_write(buf, i); +- punc_mask = saved_punc_mask; ++ spk_punc_mask = saved_punc_mask; + } + + static void say_prev_line(struct vc_data *vc) +@@ -792,7 +792,7 @@ static int say_from_to(struct vc_data *vc, u_long from, u_long to, + { + int i = 0; + u_char tmp; +- u_short saved_punc_mask = punc_mask; ++ u_short saved_punc_mask = spk_punc_mask; + spk_old_attr = spk_attr; + spk_attr = get_attributes((u_short *) from); + while (from < to) { +@@ -809,10 +809,10 @@ static int say_from_to(struct vc_data *vc, u_long from, u_long to, + if (i < 1) + return i; + if (read_punc) +- punc_mask = punc_info[reading_punc].mask; ++ spk_punc_mask = spk_punc_info[spk_reading_punc].mask; + spkup_write(buf, i); + if (read_punc) +- punc_mask = saved_punc_mask; ++ spk_punc_mask = saved_punc_mask; + return i - 1; + } + +@@ -824,7 +824,7 @@ static void say_line_from_to(struct vc_data *vc, u_long from, u_long to, + start += from * 2; + if (say_from_to(vc, start, end, read_punc) <= 0) + if (cursor_track != read_all_mode) +- synth_printf("%s\n", msg_get(MSG_BLANK)); ++ synth_printf("%s\n", spk_msg_get(MSG_BLANK)); + } + + /* Sentence Reading Commands */ +@@ -924,7 +924,7 @@ static void speakup_win_say(struct vc_data *vc) + { + u_long start, end, from, to; + if (win_start < 2) { +- synth_printf("%s\n", msg_get(MSG_NO_WINDOW)); ++ synth_printf("%s\n", spk_msg_get(MSG_NO_WINDOW)); + return; + } + start = vc->vc_origin + (win_top * vc->vc_size_row); +@@ -975,7 +975,7 @@ static void say_first_char(struct vc_data *vc) + u_char ch; + spk_parked |= 0x01; + if (len == 0) { +- synth_printf("%s\n", msg_get(MSG_BLANK)); ++ synth_printf("%s\n", spk_msg_get(MSG_BLANK)); + return; + } + for (i = 0; i < len; i++) +@@ -994,7 +994,7 @@ static void say_last_char(struct vc_data *vc) + u_char ch; + spk_parked |= 0x01; + if (len == 0) { +- synth_printf("%s\n", msg_get(MSG_BLANK)); ++ synth_printf("%s\n", spk_msg_get(MSG_BLANK)); + return; + } + ch = buf[--len]; +@@ -1006,7 +1006,7 @@ static void say_last_char(struct vc_data *vc) + + static void say_position(struct vc_data *vc) + { +- synth_printf(msg_get(MSG_POS_INFO), spk_y + 1, spk_x + 1, ++ synth_printf(spk_msg_get(MSG_POS_INFO), spk_y + 1, spk_x + 1, + vc->vc_num + 1); + synth_printf("\n"); + } +@@ -1017,7 +1017,7 @@ static void say_char_num(struct vc_data *vc) + u_char tmp; + u_short ch = get_char(vc, (u_short *) spk_pos, &tmp); + ch &= 0xff; +- synth_printf(msg_get(MSG_CHAR_INFO), ch, ch); ++ synth_printf(spk_msg_get(MSG_CHAR_INFO), ch, ch); + } + + /* these are stub functions to keep keyboard.c happy. */ +@@ -1066,7 +1066,7 @@ static void spkup_write(const char *in_buf, int count) + } else { + if ((last_type & CH_RPT) && rep_count > 2) { + synth_printf(" "); +- synth_printf(msg_get(MSG_REPEAT_DESC), ++ synth_printf(spk_msg_get(MSG_REPEAT_DESC), + ++rep_count); + synth_printf(" "); + } +@@ -1074,7 +1074,7 @@ static void spkup_write(const char *in_buf, int count) + } + if (ch == spk_lastkey) { + rep_count = 0; +- if (key_echo == 1 && ch >= MINECHOCHAR) ++ if (spk_key_echo == 1 && ch >= MINECHOCHAR) + speak_char(ch); + } else if (char_type & B_ALPHA) { + if ((synth_flags & SF_DEC) && (last_type & PUNC)) +@@ -1083,7 +1083,7 @@ static void spkup_write(const char *in_buf, int count) + } else if (char_type & B_NUM) { + rep_count = 0; + synth_printf("%c", ch); +- } else if (char_type & punc_mask) { ++ } else if (char_type & spk_punc_mask) { + speak_char(ch); + char_type &= ~PUNC; /* for dec nospell processing */ + } else if (char_type & SYNTH_OK) { +@@ -1111,7 +1111,7 @@ static void spkup_write(const char *in_buf, int count) + if (in_count > 2 && rep_count > 2) { + if (last_type & CH_RPT) { + synth_printf(" "); +- synth_printf(msg_get(MSG_REPEAT_DESC2), ++rep_count); ++ synth_printf(spk_msg_get(MSG_REPEAT_DESC2), ++rep_count); + synth_printf(" "); + } + rep_count = 0; +@@ -1135,22 +1135,22 @@ static void do_handle_shift(struct vc_data *vc, u_char value, char up_flag) + case KVAL(K_SHIFT): + del_timer(&cursor_timer); + spk_shut_up &= 0xfe; +- do_flush(); ++ spk_do_flush(); + read_all_doc(vc); + break; + case KVAL(K_CTRL): + del_timer(&cursor_timer); + cursor_track = prev_cursor_track; + spk_shut_up &= 0xfe; +- do_flush(); ++ spk_do_flush(); + break; + } + } else { + spk_shut_up &= 0xfe; +- do_flush(); ++ spk_do_flush(); + } +- if (say_ctrl && value < NUM_CTL_LABELS) +- synth_printf("%s", msg_get(MSG_CTL_START + value)); ++ if (spk_say_ctrl && value < NUM_CTL_LABELS) ++ synth_printf("%s", spk_msg_get(MSG_CTL_START + value)); + spk_unlock(flags); + } + +@@ -1171,12 +1171,12 @@ static void do_handle_latin(struct vc_data *vc, u_char value, char up_flag) + spk_lastkey = value; + spk_keydown++; + spk_parked &= 0xfe; +- if (key_echo == 2 && value >= MINECHOCHAR) ++ if (spk_key_echo == 2 && value >= MINECHOCHAR) + speak_char(value); + spk_unlock(flags); + } + +-int set_key_info(const u_char *key_info, u_char *k_buffer) ++int spk_set_key_info(const u_char *key_info, u_char *k_buffer) + { + int i = 0, states, key_data_len; + const u_char *cp = key_info; +@@ -1188,12 +1188,12 @@ int set_key_info(const u_char *key_info, u_char *k_buffer) + num_keys = *cp; + states = (int)cp[1]; + key_data_len = (states + 1) * (num_keys + 1); +- if (key_data_len + SHIFT_TBL_SIZE + 4 >= sizeof(key_buf)) ++ if (key_data_len + SHIFT_TBL_SIZE + 4 >= sizeof(spk_key_buf)) + return -2; + memset(k_buffer, 0, SHIFT_TBL_SIZE); +- memset(our_keys, 0, sizeof(our_keys)); +- shift_table = k_buffer; +- our_keys[0] = shift_table; ++ memset(spk_our_keys, 0, sizeof(spk_our_keys)); ++ spk_shift_table = k_buffer; ++ spk_our_keys[0] = spk_shift_table; + cp1 += SHIFT_TBL_SIZE; + memcpy(cp1, cp, key_data_len + 3); + /* get num_keys, states and data */ +@@ -1202,13 +1202,13 @@ int set_key_info(const u_char *key_info, u_char *k_buffer) + ch = *cp1++; + if (ch >= SHIFT_TBL_SIZE) + return -3; +- shift_table[ch] = i; ++ spk_shift_table[ch] = i; + } + keymap_flags = *cp1++; + while ((ch = *cp1)) { + if (ch >= MAX_KEY) + return -4; +- our_keys[ch] = cp1; ++ spk_our_keys[ch] = cp1; + cp1 += states + 1; + } + return 0; +@@ -1237,24 +1237,24 @@ static void toggle_cursoring(struct vc_data *vc) + cursor_track = prev_cursor_track; + if (++cursor_track >= CT_Max) + cursor_track = 0; +- synth_printf("%s\n", msg_get(MSG_CURSOR_MSGS_START + cursor_track)); ++ synth_printf("%s\n", spk_msg_get(MSG_CURSOR_MSGS_START + cursor_track)); + } + +-void reset_default_chars(void) ++void spk_reset_default_chars(void) + { + int i; + + /* First, free any non-default */ + for (i = 0; i < 256; i++) { +- if ((characters[i] != NULL) +- && (characters[i] != default_chars[i])) +- kfree(characters[i]); ++ if ((spk_characters[i] != NULL) ++ && (spk_characters[i] != spk_default_chars[i])) ++ kfree(spk_characters[i]); + } + +- memcpy(characters, default_chars, sizeof(default_chars)); ++ memcpy(spk_characters, spk_default_chars, sizeof(spk_default_chars)); + } + +-void reset_default_chartab(void) ++void spk_reset_default_chartab(void) + { + memcpy(spk_chartab, default_chartab, sizeof(default_chartab)); + } +@@ -1267,8 +1267,8 @@ static int edit_bits(struct vc_data *vc, u_char type, u_char ch, u_short key) + if (type != KT_LATIN || (ch_type & B_NUM) || ch < SPACE) + return -1; + if (ch == SPACE) { +- synth_printf("%s\n", msg_get(MSG_EDIT_DONE)); +- special_handler = NULL; ++ synth_printf("%s\n", spk_msg_get(MSG_EDIT_DONE)); ++ spk_special_handler = NULL; + return 1; + } + if (mask < PUNC && !(ch_type & PUNC)) +@@ -1276,8 +1276,8 @@ static int edit_bits(struct vc_data *vc, u_char type, u_char ch, u_short key) + spk_chartab[ch] ^= mask; + speak_char(ch); + synth_printf(" %s\n", +- (spk_chartab[ch] & mask) ? msg_get(MSG_ON) : +- msg_get(MSG_OFF)); ++ (spk_chartab[ch] & mask) ? spk_msg_get(MSG_ON) : ++ spk_msg_get(MSG_OFF)); + return 1; + } + +@@ -1346,7 +1346,7 @@ static void read_all_doc(struct vc_data *vc) + if (cursor_track != read_all_mode) + prev_cursor_track = cursor_track; + cursor_track = read_all_mode; +- reset_index_count(0); ++ spk_reset_index_count(0); + if (get_sentence_buf(vc, 0) == -1) + kbd_fakekey2(vc, RA_DOWN_ARROW); + else { +@@ -1361,7 +1361,7 @@ static void stop_read_all(struct vc_data *vc) + del_timer(&cursor_timer); + cursor_track = prev_cursor_track; + spk_shut_up &= 0xfe; +- do_flush(); ++ spk_do_flush(); + } + + static void start_read_all_timer(struct vc_data *vc, int command) +@@ -1370,7 +1370,7 @@ static void start_read_all_timer(struct vc_data *vc, int command) + + cursor_con = vc->vc_num; + read_all_key = command; +- cursor_timeout = get_var(CURSOR_TIME); ++ cursor_timeout = spk_get_var(CURSOR_TIME); + mod_timer(&cursor_timer, + jiffies + msecs_to_jiffies(cursor_timeout->u.n.value)); + } +@@ -1382,9 +1382,9 @@ static void handle_cursor_read_all(struct vc_data *vc, int command) + switch (command) { + case RA_NEXT_SENT: + /* Get Current Sentence */ +- get_index_count(&indcount, &sentcount); ++ spk_get_index_count(&indcount, &sentcount); + /*printk("%d %d ", indcount, sentcount); */ +- reset_index_count(sentcount + 1); ++ spk_reset_index_count(sentcount + 1); + if (indcount == 1) { + if (!say_sentence_num(sentcount + 1, 0)) { + kbd_fakekey2(vc, RA_FIND_NEXT_SENT); +@@ -1395,7 +1395,7 @@ static void handle_cursor_read_all(struct vc_data *vc, int command) + sn = 0; + if (!say_sentence_num(sentcount + 1, 1)) { + sn = 1; +- reset_index_count(sn); ++ spk_reset_index_count(sn); + } else + synth_insert_next_index(0); + if (!say_sentence_num(sn, 0)) { +@@ -1437,7 +1437,7 @@ static void handle_cursor_read_all(struct vc_data *vc, int command) + case RA_FIND_PREV_SENT: + break; + case RA_TIMER: +- get_index_count(&indcount, &sentcount); ++ spk_get_index_count(&indcount, &sentcount); + if (indcount < 2) + kbd_fakekey2(vc, RA_DOWN_ARROW); + else +@@ -1458,7 +1458,7 @@ static int pre_handle_cursor(struct vc_data *vc, u_char value, char up_flag) + } + del_timer(&cursor_timer); + spk_shut_up &= 0xfe; +- do_flush(); ++ spk_do_flush(); + start_read_all_timer(vc, value + 1); + spk_unlock(flags); + return NOTIFY_STOP; +@@ -1479,8 +1479,8 @@ static void do_handle_cursor(struct vc_data *vc, u_char value, char up_flag) + return; + } + spk_shut_up &= 0xfe; +- if (no_intr) +- do_flush(); ++ if (spk_no_intr) ++ spk_do_flush(); + /* the key press flushes if !no_inter but we want to flush on cursor + * moves regardless of no_inter state */ + is_cursor = value + 1; +@@ -1491,7 +1491,7 @@ static void do_handle_cursor(struct vc_data *vc, u_char value, char up_flag) + cursor_con = vc->vc_num; + if (cursor_track == CT_Highlight) + reset_highlight_buffers(vc); +- cursor_timeout = get_var(CURSOR_TIME); ++ cursor_timeout = spk_get_var(CURSOR_TIME); + mod_timer(&cursor_timer, + jiffies + msecs_to_jiffies(cursor_timeout->u.n.value)); + spk_unlock(flags); +@@ -1603,7 +1603,7 @@ static int speak_highlight(struct vc_data *vc) + if (speakup_console[vc_num]->ht.ry[hc] != vc->vc_y) + return 0; + spk_parked |= 0x01; +- do_flush(); ++ spk_do_flush(); + spkup_write(speakup_console[vc_num]->ht.highbuf[hc], + speakup_console[vc_num]->ht.highsize[hc]); + spk_pos = spk_cp = speakup_console[vc_num]->ht.rpos[hc]; +@@ -1685,7 +1685,7 @@ static void speakup_con_write(struct vc_data *vc, const char *str, int len) + if (!spk_trylock(flags)) + /* Speakup output, discard */ + return; +- if (bell_pos && spk_keydown && (vc->vc_x == bell_pos - 1)) ++ if (spk_bell_pos && spk_keydown && (vc->vc_x == spk_bell_pos - 1)) + bleep(3); + if ((is_cursor) || (cursor_track == read_all_mode)) { + if (cursor_track == CT_Highlight) +@@ -1726,19 +1726,19 @@ static void do_handle_spec(struct vc_data *vc, u_char value, char up_flag) + return; + spk_lock(flags); + spk_shut_up &= 0xfe; +- if (no_intr) +- do_flush(); ++ if (spk_no_intr) ++ spk_do_flush(); + switch (value) { + case KVAL(K_CAPS): +- label = msg_get(MSG_KEYNAME_CAPSLOCK); ++ label = spk_msg_get(MSG_KEYNAME_CAPSLOCK); + on_off = vt_get_leds(fg_console, VC_CAPSLOCK); + break; + case KVAL(K_NUM): +- label = msg_get(MSG_KEYNAME_NUMLOCK); ++ label = spk_msg_get(MSG_KEYNAME_NUMLOCK); + on_off = vt_get_leds(fg_console, VC_NUMLOCK); + break; + case KVAL(K_HOLD): +- label = msg_get(MSG_KEYNAME_SCROLLLOCK); ++ label = spk_msg_get(MSG_KEYNAME_SCROLLLOCK); + on_off = vt_get_leds(fg_console, VC_SCROLLOCK); + if (speakup_console[vc->vc_num]) + speakup_console[vc->vc_num]->tty_stopped = on_off; +@@ -1750,7 +1750,7 @@ static void do_handle_spec(struct vc_data *vc, u_char value, char up_flag) + } + if (on_off < 2) + synth_printf("%s %s\n", +- label, msg_get(MSG_STATUS_START + on_off)); ++ label, spk_msg_get(MSG_STATUS_START + on_off)); + spk_unlock(flags); + } + +@@ -1764,13 +1764,13 @@ static int inc_dec_var(u_char value) + int var_id = (int)value - VAR_START; + int how = (var_id & 1) ? E_INC : E_DEC; + var_id = var_id / 2 + FIRST_SET_VAR; +- p_header = get_var_header(var_id); ++ p_header = spk_get_var_header(var_id); + if (p_header == NULL) + return -1; + if (p_header->var_type != VAR_NUM) + return -1; + var_data = p_header->data; +- if (set_num_var(1, p_header, how) != 0) ++ if (spk_set_num_var(1, p_header, how) != 0) + return -1; + if (!spk_close_press) { + for (pn = p_header->name; *pn; pn++) { +@@ -1790,18 +1790,18 @@ static void speakup_win_set(struct vc_data *vc) + { + char info[40]; + if (win_start > 1) { +- synth_printf("%s\n", msg_get(MSG_WINDOW_ALREADY_SET)); ++ synth_printf("%s\n", spk_msg_get(MSG_WINDOW_ALREADY_SET)); + return; + } + if (spk_x < win_left || spk_y < win_top) { +- synth_printf("%s\n", msg_get(MSG_END_BEFORE_START)); ++ synth_printf("%s\n", spk_msg_get(MSG_END_BEFORE_START)); + return; + } + if (win_start && spk_x == win_left && spk_y == win_top) { + win_left = 0; + win_right = vc->vc_cols - 1; + win_bottom = spk_y; +- snprintf(info, sizeof(info), msg_get(MSG_WINDOW_LINE), ++ snprintf(info, sizeof(info), spk_msg_get(MSG_WINDOW_LINE), + (int)win_top + 1); + } else { + if (!win_start) { +@@ -1811,8 +1811,8 @@ static void speakup_win_set(struct vc_data *vc) + win_bottom = spk_y; + win_right = spk_x; + } +- snprintf(info, sizeof(info), msg_get(MSG_WINDOW_BOUNDARY), +- (win_start) ? msg_get(MSG_END) : msg_get(MSG_START), ++ snprintf(info, sizeof(info), spk_msg_get(MSG_WINDOW_BOUNDARY), ++ (win_start) ? spk_msg_get(MSG_END) : spk_msg_get(MSG_START), + (int)spk_y + 1, (int)spk_x + 1); + } + synth_printf("%s\n", info); +@@ -1824,32 +1824,32 @@ static void speakup_win_clear(struct vc_data *vc) + win_top = win_bottom = 0; + win_left = win_right = 0; + win_start = 0; +- synth_printf("%s\n", msg_get(MSG_WINDOW_CLEARED)); ++ synth_printf("%s\n", spk_msg_get(MSG_WINDOW_CLEARED)); + } + + static void speakup_win_enable(struct vc_data *vc) + { + if (win_start < 2) { +- synth_printf("%s\n", msg_get(MSG_NO_WINDOW)); ++ synth_printf("%s\n", spk_msg_get(MSG_NO_WINDOW)); + return; + } + win_enabled ^= 1; + if (win_enabled) +- synth_printf("%s\n", msg_get(MSG_WINDOW_SILENCED)); ++ synth_printf("%s\n", spk_msg_get(MSG_WINDOW_SILENCED)); + else +- synth_printf("%s\n", msg_get(MSG_WINDOW_SILENCE_DISABLED)); ++ synth_printf("%s\n", spk_msg_get(MSG_WINDOW_SILENCE_DISABLED)); + } + + static void speakup_bits(struct vc_data *vc) + { + int val = this_speakup_key - (FIRST_EDIT_BITS - 1); +- if (special_handler != NULL || val < 1 || val > 6) { +- synth_printf("%s\n", msg_get(MSG_ERROR)); ++ if (spk_special_handler != NULL || val < 1 || val > 6) { ++ synth_printf("%s\n", spk_msg_get(MSG_ERROR)); + return; + } +- pb_edit = &punc_info[val]; +- synth_printf(msg_get(MSG_EDIT_PROMPT), pb_edit->name); +- special_handler = edit_bits; ++ pb_edit = &spk_punc_info[val]; ++ synth_printf(spk_msg_get(MSG_EDIT_PROMPT), pb_edit->name); ++ spk_special_handler = edit_bits; + } + + static int handle_goto(struct vc_data *vc, u_char type, u_char ch, u_short key) +@@ -1887,9 +1887,9 @@ static int handle_goto(struct vc_data *vc, u_char type, u_char ch, u_short key) + if (ch < 'x' || ch > 'y') { + oops: + if (!spk_killed) +- synth_printf(" %s\n", msg_get(MSG_GOTO_CANCELED)); ++ synth_printf(" %s\n", spk_msg_get(MSG_GOTO_CANCELED)); + goto_buf[num = 0] = '\0'; +- special_handler = NULL; ++ spk_special_handler = NULL; + return 1; + } + cp = speakup_s2i(goto_buf, &go_pos); +@@ -1917,7 +1917,7 @@ oops: + } + goto_buf[num = 0] = '\0'; + do_goto: +- special_handler = NULL; ++ spk_special_handler = NULL; + spk_parked |= 0x01; + if (goto_x) { + spk_pos -= spk_x * 2; +@@ -1934,18 +1934,18 @@ do_goto: + + static void speakup_goto(struct vc_data *vc) + { +- if (special_handler != NULL) { +- synth_printf("%s\n", msg_get(MSG_ERROR)); ++ if (spk_special_handler != NULL) { ++ synth_printf("%s\n", spk_msg_get(MSG_ERROR)); + return; + } +- synth_printf("%s\n", msg_get(MSG_GOTO)); +- special_handler = handle_goto; ++ synth_printf("%s\n", spk_msg_get(MSG_GOTO)); ++ spk_special_handler = handle_goto; + return; + } + + static void speakup_help(struct vc_data *vc) + { +- handle_help(vc, KT_SPKUP, SPEAKUP_HELP, 0); ++ spk_handle_help(vc, KT_SPKUP, SPEAKUP_HELP, 0); + } + + static void do_nothing(struct vc_data *vc) +@@ -1992,7 +1992,7 @@ static void do_spkup(struct vc_data *vc, u_char value) + spk_shut_up &= 0xfe; + this_speakup_key = value; + if (value < SPKUP_MAX_FUNC && spkup_handler[value]) { +- do_flush(); ++ spk_do_flush(); + (*spkup_handler[value]) (vc); + } else { + if (inc_dec_var(value) < 0) +@@ -2032,7 +2032,7 @@ speakup_key(struct vc_data *vc, int shift_state, int keycode, u_short keysym, + } + if (keycode >= MAX_KEY) + goto no_map; +- key_info = our_keys[keycode]; ++ key_info = spk_our_keys[keycode]; + if (key_info == 0) + goto no_map; + /* Check valid read all mode keys */ +@@ -2051,7 +2051,7 @@ speakup_key(struct vc_data *vc, int shift_state, int keycode, u_short keysym, + } + } + shift_info = (shift_state & 0x0f) + key_speakup; +- offset = shift_table[shift_info]; ++ offset = spk_shift_table[shift_info]; + if (offset) { + new_key = key_info[offset]; + if (new_key) { +@@ -2062,7 +2062,7 @@ speakup_key(struct vc_data *vc, int shift_state, int keycode, u_short keysym, + if (up_flag || spk_killed) + goto out; + spk_shut_up &= 0xfe; +- do_flush(); ++ spk_do_flush(); + goto out; + } + if (up_flag) +@@ -2070,7 +2070,7 @@ speakup_key(struct vc_data *vc, int shift_state, int keycode, u_short keysym, + if (last_keycode == keycode && + last_spk_jiffy + MAX_DELAY > jiffies) { + spk_close_press = 1; +- offset = shift_table[shift_info + 32]; ++ offset = spk_shift_table[shift_info + 32]; + /* double press? */ + if (offset && key_info[offset]) + new_key = key_info[offset]; +@@ -2082,7 +2082,7 @@ speakup_key(struct vc_data *vc, int shift_state, int keycode, u_short keysym, + } + } + no_map: +- if (type == KT_SPKUP && special_handler == NULL) { ++ if (type == KT_SPKUP && spk_special_handler == NULL) { + do_spkup(vc, new_key); + spk_close_press = 0; + ret = 1; +@@ -2096,9 +2096,9 @@ no_map: + || (value == KVAL(K_LEFT)) + || (value == KVAL(K_RIGHT)); + if ((cursor_track != read_all_mode) || !kh) +- if (!no_intr) +- do_flush(); +- if (special_handler) { ++ if (!spk_no_intr) ++ spk_do_flush(); ++ if (spk_special_handler) { + if (type == KT_SPEC && value == 1) { + value = '\n'; + type = KT_LATIN; +@@ -2106,7 +2106,7 @@ no_map: + type = KT_LATIN; + else if (value == 0x7f) + value = 8; /* make del = backspace */ +- ret = (*special_handler) (vc, type, value, keycode); ++ ret = (*spk_special_handler) (vc, type, value, keycode); + spk_close_press = 0; + if (ret < 0) + bleep(9); +@@ -2237,11 +2237,11 @@ static void __exit speakup_exit(void) + speakup_unregister_var(i); + + for (i = 0; i < 256; i++) { +- if (characters[i] != default_chars[i]) +- kfree(characters[i]); ++ if (spk_characters[i] != spk_default_chars[i]) ++ kfree(spk_characters[i]); + } + +- free_user_msgs(); ++ spk_free_user_msgs(); + } + + /* call by: module_init() */ +@@ -2254,20 +2254,20 @@ static int __init speakup_init(void) + struct var_t *var; + + /* These first few initializations cannot fail. */ +- initialize_msgs(); /* Initialize arrays for i18n. */ +- reset_default_chars(); +- reset_default_chartab(); +- strlwr(synth_name); ++ spk_initialize_msgs(); /* Initialize arrays for i18n. */ ++ spk_reset_default_chars(); ++ spk_reset_default_chartab(); ++ spk_strlwr(synth_name); + spk_vars[0].u.n.high = vc->vc_cols; + for (var = spk_vars; var->var_id != MAXVARS; var++) + speakup_register_var(var); + for (var = synth_time_vars; + (var->var_id >= 0) && (var->var_id < MAXVARS); var++) + speakup_register_var(var); +- for (i = 1; punc_info[i].mask != 0; i++) +- set_mask_bits(0, i, 2); ++ for (i = 1; spk_punc_info[i].mask != 0; i++) ++ spk_set_mask_bits(0, i, 2); + +- set_key_info(key_defaults, key_buf); ++ spk_set_key_info(spk_key_defaults, spk_key_buf); + + /* From here on out, initializations can fail. */ + err = speakup_add_virtual_keyboard(); +@@ -2290,7 +2290,7 @@ static int __init speakup_init(void) + goto error_kobjects; + } + +- if (quiet_boot) ++ if (spk_quiet_boot) + spk_shut_up |= 0x01; + + err = speakup_kobj_init(); +@@ -2352,11 +2352,11 @@ error_virtkeyboard: + speakup_unregister_var(i); + + for (i = 0; i < 256; i++) { +- if (characters[i] != default_chars[i]) +- kfree(characters[i]); ++ if (spk_characters[i] != spk_default_chars[i]) ++ kfree(spk_characters[i]); + } + +- free_user_msgs(); ++ spk_free_user_msgs(); + + out: + return err; +diff --git a/drivers/staging/speakup/selection.c b/drivers/staging/speakup/selection.c +index fe1f405d5d70..1217c79ed712 100644 +--- a/drivers/staging/speakup/selection.c ++++ b/drivers/staging/speakup/selection.c +@@ -10,7 +10,7 @@ + /* Don't take this from : 011-015 on the screen aren't spaces */ + #define ishardspace(c) ((c) == ' ') + +-unsigned short xs, ys, xe, ye; /* our region points */ ++unsigned short spk_xs, spk_ys, spk_xe, spk_ye; /* our region points */ + + /* Variables for selection control. */ + /* must not be disallocated */ +@@ -51,12 +51,12 @@ int speakup_set_selection(struct tty_struct *tty) + int i, ps, pe; + struct vc_data *vc = vc_cons[fg_console].d; + +- xs = limit(xs, vc->vc_cols - 1); +- ys = limit(ys, vc->vc_rows - 1); +- xe = limit(xe, vc->vc_cols - 1); +- ye = limit(ye, vc->vc_rows - 1); +- ps = ys * vc->vc_size_row + (xs << 1); +- pe = ye * vc->vc_size_row + (xe << 1); ++ spk_xs = limit(spk_xs, vc->vc_cols - 1); ++ spk_ys = limit(spk_ys, vc->vc_rows - 1); ++ spk_xe = limit(spk_xe, vc->vc_cols - 1); ++ spk_ye = limit(spk_ye, vc->vc_rows - 1); ++ ps = spk_ys * vc->vc_size_row + (spk_xs << 1); ++ pe = spk_ye * vc->vc_size_row + (spk_xe << 1); + + if (ps > pe) { + /* make sel_start <= sel_end */ +diff --git a/drivers/staging/speakup/serialio.c b/drivers/staging/speakup/serialio.c +index a97d3d5b58a4..e4d27aa2898f 100644 +--- a/drivers/staging/speakup/serialio.c ++++ b/drivers/staging/speakup/serialio.c +@@ -116,7 +116,7 @@ static void start_serial_interrupt(int irq) + outb(1, speakup_info.port_tts + UART_FCR); /* Turn FIFO On */ + } + +-void stop_serial_interrupt(void) ++void spk_stop_serial_interrupt(void) + { + if (speakup_info.port_tts == 0) + return; +@@ -130,7 +130,7 @@ void stop_serial_interrupt(void) + free_irq(serstate->irq, (void *) synth_readbuf_handler); + } + +-int wait_for_xmitr(void) ++int spk_wait_for_xmitr(void) + { + int tmout = SPK_XMITR_TIMEOUT; + if ((synth->alive) && (timeouts >= NUM_DISABLE_TIMEOUTS)) { +@@ -195,7 +195,7 @@ EXPORT_SYMBOL_GPL(spk_serial_in_nowait); + + int spk_serial_out(const char ch) + { +- if (synth->alive && wait_for_xmitr()) { ++ if (synth->alive && spk_wait_for_xmitr()) { + outb_p(ch, speakup_info.port_tts); + return 1; + } +diff --git a/drivers/staging/speakup/speakup.h b/drivers/staging/speakup/speakup.h +index e66579e6147a..22f0fbb85f42 100644 +--- a/drivers/staging/speakup/speakup.h ++++ b/drivers/staging/speakup/speakup.h +@@ -50,34 +50,34 @@ + #define E_UNDEF -1 + + extern int speakup_thread(void *data); +-extern void reset_default_chars(void); +-extern void reset_default_chartab(void); ++extern void spk_reset_default_chars(void); ++extern void spk_reset_default_chartab(void); + extern void synth_start(void); + void synth_insert_next_index(int sent_num); +-void reset_index_count(int sc); +-void get_index_count(int *linecount, int *sentcount); +-extern int set_key_info(const u_char *key_info, u_char *k_buffer); +-extern char *strlwr(char *s); ++void spk_reset_index_count(int sc); ++void spk_get_index_count(int *linecount, int *sentcount); ++extern int spk_set_key_info(const u_char *key_info, u_char *k_buffer); ++extern char *spk_strlwr(char *s); + extern char *speakup_s2i(char *start, int *dest); +-extern char *s2uchar(char *start, char *dest); +-extern char *xlate(char *s); ++extern char *spk_s2uchar(char *start, char *dest); ++extern char *spk_xlate(char *s); + extern int speakup_kobj_init(void); + extern void speakup_kobj_exit(void); +-extern int chartab_get_value(char *keyword); ++extern int spk_chartab_get_value(char *keyword); + extern void speakup_register_var(struct var_t *var); + extern void speakup_unregister_var(enum var_id_t var_id); +-extern struct st_var_header *get_var_header(enum var_id_t var_id); +-extern struct st_var_header *var_header_by_name(const char *name); +-extern struct punc_var_t *get_punc_var(enum var_id_t var_id); +-extern int set_num_var(int val, struct st_var_header *var, int how); +-extern int set_string_var(const char *page, struct st_var_header *var, int len); +-extern int set_mask_bits(const char *input, const int which, const int how); +-extern special_func special_handler; +-extern int handle_help(struct vc_data *vc, u_char type, u_char ch, u_short key); ++extern struct st_var_header *spk_get_var_header(enum var_id_t var_id); ++extern struct st_var_header *spk_var_header_by_name(const char *name); ++extern struct punc_var_t *spk_get_punc_var(enum var_id_t var_id); ++extern int spk_set_num_var(int val, struct st_var_header *var, int how); ++extern int spk_set_string_var(const char *page, struct st_var_header *var, int len); ++extern int spk_set_mask_bits(const char *input, const int which, const int how); ++extern special_func spk_special_handler; ++extern int spk_handle_help(struct vc_data *vc, u_char type, u_char ch, u_short key); + extern int synth_init(char *name); + extern void synth_release(void); + +-extern void do_flush(void); ++extern void spk_do_flush(void); + extern void speakup_start_ttys(void); + extern void synth_buffer_add(char ch); + extern void synth_buffer_clear(void); +@@ -90,35 +90,35 @@ extern void synth_write(const char *buf, size_t count); + extern int synth_supports_indexing(void); + + extern struct vc_data *spk_sel_cons; +-extern unsigned short xs, ys, xe, ye; /* our region points */ ++extern unsigned short spk_xs, spk_ys, spk_xe, spk_ye; /* our region points */ + + extern wait_queue_head_t speakup_event; + extern struct kobject *speakup_kobj; + extern struct task_struct *speakup_task; +-extern const u_char key_defaults[]; ++extern const u_char spk_key_defaults[]; + + /* Protect speakup synthesizer list */ + extern struct mutex spk_mutex; + extern struct st_spk_t *speakup_console[]; + extern struct spk_synth *synth; +-extern char pitch_buff[]; +-extern u_char *our_keys[]; +-extern short punc_masks[]; +-extern char str_caps_start[], str_caps_stop[]; +-extern const struct st_bits_data punc_info[]; +-extern u_char key_buf[600]; +-extern char *characters[]; +-extern char *default_chars[]; ++extern char spk_pitch_buff[]; ++extern u_char *spk_our_keys[]; ++extern short spk_punc_masks[]; ++extern char spk_str_caps_start[], spk_str_caps_stop[]; ++extern const struct st_bits_data spk_punc_info[]; ++extern u_char spk_key_buf[600]; ++extern char *spk_characters[]; ++extern char *spk_default_chars[]; + extern u_short spk_chartab[]; +-extern int no_intr, say_ctrl, say_word_ctl, punc_level; +-extern int reading_punc, attrib_bleep, bleeps; +-extern int bleep_time, bell_pos; +-extern int spell_delay, key_echo; +-extern short punc_mask; +-extern short pitch_shift, synth_flags; +-extern bool quiet_boot; ++extern int spk_no_intr, spk_say_ctrl, spk_say_word_ctl, spk_punc_level; ++extern int spk_reading_punc, spk_attrib_bleep, spk_bleeps; ++extern int spk_bleep_time, spk_bell_pos; ++extern int spk_spell_delay, spk_key_echo; ++extern short spk_punc_mask; ++extern short spk_pitch_shift, synth_flags; ++extern bool spk_quiet_boot; + extern char *synth_name; +-extern struct bleep unprocessed_sound; ++extern struct bleep spk_unprocessed_sound; + + /* Prototypes from fakekey.c. */ + int speakup_add_virtual_keyboard(void); +diff --git a/drivers/staging/speakup/speakup_acntpc.c b/drivers/staging/speakup/speakup_acntpc.c +index bbe28b6809e0..1c1f0d560449 100644 +--- a/drivers/staging/speakup/speakup_acntpc.c ++++ b/drivers/staging/speakup/speakup_acntpc.c +@@ -182,9 +182,9 @@ static void do_catch_up(struct spk_synth *synth) + struct var_t *full_time; + struct var_t *jiffy_delta; + +- jiffy_delta = get_var(JIFFY); +- delay_time = get_var(DELAY); +- full_time = get_var(FULL); ++ jiffy_delta = spk_get_var(JIFFY); ++ delay_time = spk_get_var(DELAY); ++ full_time = spk_get_var(FULL); + + spk_lock(flags); + jiffy_delta_val = jiffy_delta->u.n.value; +diff --git a/drivers/staging/speakup/speakup_acntsa.c b/drivers/staging/speakup/speakup_acntsa.c +index 590fa6bb0ed4..22a8b7291098 100644 +--- a/drivers/staging/speakup/speakup_acntsa.c ++++ b/drivers/staging/speakup/speakup_acntsa.c +@@ -128,7 +128,7 @@ static int synth_probe(struct spk_synth *synth) + { + int failed; + +- failed = serial_synth_probe(synth); ++ failed = spk_serial_synth_probe(synth); + if (failed == 0) { + spk_synth_immediate(synth, "\033=R\r"); + mdelay(100); +diff --git a/drivers/staging/speakup/speakup_apollo.c b/drivers/staging/speakup/speakup_apollo.c +index 00d5cedd00ab..3e450ccbda66 100644 +--- a/drivers/staging/speakup/speakup_apollo.c ++++ b/drivers/staging/speakup/speakup_apollo.c +@@ -112,7 +112,7 @@ static struct spk_synth synth_apollo = { + .startup = SYNTH_START, + .checkval = SYNTH_CHECK, + .vars = vars, +- .probe = serial_synth_probe, ++ .probe = spk_serial_synth_probe, + .release = spk_serial_release, + .synth_immediate = spk_synth_immediate, + .catch_up = do_catch_up, +@@ -145,9 +145,9 @@ static void do_catch_up(struct spk_synth *synth) + int delay_time_val = 0; + int jiffy_delta_val = 0; + +- jiffy_delta = get_var(JIFFY); +- delay_time = get_var(DELAY); +- full_time = get_var(FULL); ++ jiffy_delta = spk_get_var(JIFFY); ++ delay_time = spk_get_var(DELAY); ++ full_time = spk_get_var(FULL); + spk_lock(flags); + jiffy_delta_val = jiffy_delta->u.n.value; + spk_unlock(flags); +diff --git a/drivers/staging/speakup/speakup_audptr.c b/drivers/staging/speakup/speakup_audptr.c +index 94e509992c8b..3508aee98ab0 100644 +--- a/drivers/staging/speakup/speakup_audptr.c ++++ b/drivers/staging/speakup/speakup_audptr.c +@@ -162,7 +162,7 @@ static int synth_probe(struct spk_synth *synth) + { + int failed = 0; + +- failed = serial_synth_probe(synth); ++ failed = spk_serial_synth_probe(synth); + if (failed == 0) + synth_version(synth); + synth->alive = !failed; +diff --git a/drivers/staging/speakup/speakup_bns.c b/drivers/staging/speakup/speakup_bns.c +index 43e5b54f344c..4bfe3d458dc0 100644 +--- a/drivers/staging/speakup/speakup_bns.c ++++ b/drivers/staging/speakup/speakup_bns.c +@@ -100,7 +100,7 @@ static struct spk_synth synth_bns = { + .startup = SYNTH_START, + .checkval = SYNTH_CHECK, + .vars = vars, +- .probe = serial_synth_probe, ++ .probe = spk_serial_synth_probe, + .release = spk_serial_release, + .synth_immediate = spk_synth_immediate, + .catch_up = spk_do_catch_up, +diff --git a/drivers/staging/speakup/speakup_decext.c b/drivers/staging/speakup/speakup_decext.c +index b4ef9153f42e..d39a0de286fb 100644 +--- a/drivers/staging/speakup/speakup_decext.c ++++ b/drivers/staging/speakup/speakup_decext.c +@@ -130,7 +130,7 @@ static struct spk_synth synth_decext = { + .startup = SYNTH_START, + .checkval = SYNTH_CHECK, + .vars = vars, +- .probe = serial_synth_probe, ++ .probe = spk_serial_synth_probe, + .release = spk_serial_release, + .synth_immediate = spk_synth_immediate, + .catch_up = do_catch_up, +@@ -162,8 +162,8 @@ static void do_catch_up(struct spk_synth *synth) + int jiffy_delta_val = 0; + int delay_time_val = 0; + +- jiffy_delta = get_var(JIFFY); +- delay_time = get_var(DELAY); ++ jiffy_delta = spk_get_var(JIFFY); ++ delay_time = spk_get_var(DELAY); + + spk_lock(flags); + jiffy_delta_val = jiffy_delta->u.n.value; +diff --git a/drivers/staging/speakup/speakup_decpc.c b/drivers/staging/speakup/speakup_decpc.c +index de25527decf6..cda6b0f73c41 100644 +--- a/drivers/staging/speakup/speakup_decpc.c ++++ b/drivers/staging/speakup/speakup_decpc.c +@@ -375,8 +375,8 @@ static void do_catch_up(struct spk_synth *synth) + int jiffy_delta_val; + int delay_time_val; + +- jiffy_delta = get_var(JIFFY); +- delay_time = get_var(DELAY); ++ jiffy_delta = spk_get_var(JIFFY); ++ delay_time = spk_get_var(DELAY); + spk_lock(flags); + jiffy_delta_val = jiffy_delta->u.n.value; + spk_unlock(flags); +diff --git a/drivers/staging/speakup/speakup_dectlk.c b/drivers/staging/speakup/speakup_dectlk.c +index daff3b9a4a6d..0dd2eb96cb28 100644 +--- a/drivers/staging/speakup/speakup_dectlk.c ++++ b/drivers/staging/speakup/speakup_dectlk.c +@@ -134,7 +134,7 @@ static struct spk_synth synth_dectlk = { + .vars = vars, + .default_pitch = ap_defaults, + .default_vol = g5_defaults, +- .probe = serial_synth_probe, ++ .probe = spk_serial_synth_probe, + .release = spk_serial_release, + .synth_immediate = spk_synth_immediate, + .catch_up = do_catch_up, +@@ -214,8 +214,8 @@ static void do_catch_up(struct spk_synth *synth) + int jiffy_delta_val; + int delay_time_val; + +- jiffy_delta = get_var(JIFFY); +- delay_time = get_var(DELAY); ++ jiffy_delta = spk_get_var(JIFFY); ++ delay_time = spk_get_var(DELAY); + spk_lock(flags); + jiffy_delta_val = jiffy_delta->u.n.value; + spk_unlock(flags); +diff --git a/drivers/staging/speakup/speakup_dtlk.c b/drivers/staging/speakup/speakup_dtlk.c +index 97bc476746cd..a9cefbd3ea93 100644 +--- a/drivers/staging/speakup/speakup_dtlk.c ++++ b/drivers/staging/speakup/speakup_dtlk.c +@@ -198,8 +198,8 @@ static void do_catch_up(struct spk_synth *synth) + int jiffy_delta_val; + int delay_time_val; + +- jiffy_delta = get_var(JIFFY); +- delay_time = get_var(DELAY); ++ jiffy_delta = spk_get_var(JIFFY); ++ delay_time = spk_get_var(DELAY); + spk_lock(flags); + jiffy_delta_val = jiffy_delta->u.n.value; + spk_unlock(flags); +diff --git a/drivers/staging/speakup/speakup_dummy.c b/drivers/staging/speakup/speakup_dummy.c +index c20f41188be1..4a24b9c1e8e3 100644 +--- a/drivers/staging/speakup/speakup_dummy.c ++++ b/drivers/staging/speakup/speakup_dummy.c +@@ -102,7 +102,7 @@ static struct spk_synth synth_dummy = { + .startup = SYNTH_START, + .checkval = SYNTH_CHECK, + .vars = vars, +- .probe = serial_synth_probe, ++ .probe = spk_serial_synth_probe, + .release = spk_serial_release, + .synth_immediate = spk_synth_immediate, + .catch_up = spk_do_catch_up, +diff --git a/drivers/staging/speakup/speakup_keypc.c b/drivers/staging/speakup/speakup_keypc.c +index 496e01481f9e..feb5f22cc169 100644 +--- a/drivers/staging/speakup/speakup_keypc.c ++++ b/drivers/staging/speakup/speakup_keypc.c +@@ -184,9 +184,9 @@ static void do_catch_up(struct spk_synth *synth) + int full_time_val; + int jiffy_delta_val; + +- jiffy_delta = get_var(JIFFY); +- delay_time = get_var(DELAY); +- full_time = get_var(FULL); ++ jiffy_delta = spk_get_var(JIFFY); ++ delay_time = spk_get_var(DELAY); ++ full_time = spk_get_var(FULL); + spk_lock(flags); + jiffy_delta_val = jiffy_delta->u.n.value; + spk_unlock(flags); +diff --git a/drivers/staging/speakup/speakup_ltlk.c b/drivers/staging/speakup/speakup_ltlk.c +index 971de1a13712..326f94d6b079 100644 +--- a/drivers/staging/speakup/speakup_ltlk.c ++++ b/drivers/staging/speakup/speakup_ltlk.c +@@ -161,7 +161,7 @@ static int synth_probe(struct spk_synth *synth) + { + int failed = 0; + +- failed = serial_synth_probe(synth); ++ failed = spk_serial_synth_probe(synth); + if (failed == 0) + synth_interrogate(synth); + synth->alive = !failed; +diff --git a/drivers/staging/speakup/speakup_spkout.c b/drivers/staging/speakup/speakup_spkout.c +index 9a3a80d9701e..e74f85620c68 100644 +--- a/drivers/staging/speakup/speakup_spkout.c ++++ b/drivers/staging/speakup/speakup_spkout.c +@@ -107,7 +107,7 @@ static struct spk_synth synth_spkout = { + .startup = SYNTH_START, + .checkval = SYNTH_CHECK, + .vars = vars, +- .probe = serial_synth_probe, ++ .probe = spk_serial_synth_probe, + .release = spk_serial_release, + .synth_immediate = spk_synth_immediate, + .catch_up = spk_do_catch_up, +diff --git a/drivers/staging/speakup/speakup_txprt.c b/drivers/staging/speakup/speakup_txprt.c +index 5d5bf7c3d0b1..5a29b9fcc930 100644 +--- a/drivers/staging/speakup/speakup_txprt.c ++++ b/drivers/staging/speakup/speakup_txprt.c +@@ -100,7 +100,7 @@ static struct spk_synth synth_txprt = { + .startup = SYNTH_START, + .checkval = SYNTH_CHECK, + .vars = vars, +- .probe = serial_synth_probe, ++ .probe = spk_serial_synth_probe, + .release = spk_serial_release, + .synth_immediate = spk_synth_immediate, + .catch_up = spk_do_catch_up, +diff --git a/drivers/staging/speakup/spk_priv.h b/drivers/staging/speakup/spk_priv.h +index a47c5b78d57d..303105b46013 100644 +--- a/drivers/staging/speakup/spk_priv.h ++++ b/drivers/staging/speakup/spk_priv.h +@@ -45,8 +45,8 @@ + #define KT_SPKUP 15 + + extern const struct old_serial_port *spk_serial_init(int index); +-extern void stop_serial_interrupt(void); +-extern int wait_for_xmitr(void); ++extern void spk_stop_serial_interrupt(void); ++extern int spk_wait_for_xmitr(void); + extern unsigned char spk_serial_in(void); + extern unsigned char spk_serial_in_nowait(void); + extern int spk_serial_out(const char ch); +@@ -55,13 +55,13 @@ extern void spk_serial_release(void); + extern char synth_buffer_getc(void); + extern char synth_buffer_peek(void); + extern int synth_buffer_empty(void); +-extern struct var_t *get_var(enum var_id_t var_id); ++extern struct var_t *spk_get_var(enum var_id_t var_id); + extern ssize_t spk_var_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf); + extern ssize_t spk_var_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count); + +-extern int serial_synth_probe(struct spk_synth *synth); ++extern int spk_serial_synth_probe(struct spk_synth *synth); + extern const char *spk_synth_immediate(struct spk_synth *synth, const char *buff); + extern void spk_do_catch_up(struct spk_synth *synth); + extern void spk_synth_flush(struct spk_synth *synth); +diff --git a/drivers/staging/speakup/synth.c b/drivers/staging/speakup/synth.c +index 5710fc582beb..33efbd320930 100644 +--- a/drivers/staging/speakup/synth.c ++++ b/drivers/staging/speakup/synth.c +@@ -20,9 +20,9 @@ + #define MAXSYNTHS 16 /* Max number of synths in array. */ + static struct spk_synth *synths[MAXSYNTHS]; + struct spk_synth *synth; +-char pitch_buff[32] = ""; ++char spk_pitch_buff[32] = ""; + static int module_status; +-bool quiet_boot; ++bool spk_quiet_boot; + + struct speakup_info_t speakup_info = { + .spinlock = __SPIN_LOCK_UNLOCKED(speakup_info.spinlock), +@@ -32,7 +32,7 @@ EXPORT_SYMBOL_GPL(speakup_info); + + static int do_synth_init(struct spk_synth *in_synth); + +-int serial_synth_probe(struct spk_synth *synth) ++int spk_serial_synth_probe(struct spk_synth *synth) + { + const struct old_serial_port *ser; + int failed = 0; +@@ -59,7 +59,7 @@ int serial_synth_probe(struct spk_synth *synth) + synth->alive = 1; + return 0; + } +-EXPORT_SYMBOL_GPL(serial_synth_probe); ++EXPORT_SYMBOL_GPL(spk_serial_synth_probe); + + /* Main loop of the progression thread: keep eating from the buffer + * and push to the serial port, waiting as needed +@@ -79,9 +79,9 @@ void spk_do_catch_up(struct spk_synth *synth) + int delay_time_val; + int full_time_val; + +- jiffy_delta = get_var(JIFFY); +- full_time = get_var(FULL); +- delay_time = get_var(DELAY); ++ jiffy_delta = spk_get_var(JIFFY); ++ full_time = spk_get_var(FULL); ++ delay_time = spk_get_var(DELAY); + + spk_lock(flags); + jiffy_delta_val = jiffy_delta->u.n.value; +@@ -139,7 +139,7 @@ const char *spk_synth_immediate(struct spk_synth *synth, const char *buff) + while ((ch = *buff)) { + if (ch == '\n') + ch = synth->procspeech; +- if (wait_for_xmitr()) ++ if (spk_wait_for_xmitr()) + outb(ch, speakup_info.port_tts); + else + return buff; +@@ -166,7 +166,7 @@ int spk_synth_is_alive_restart(struct spk_synth *synth) + { + if (synth->alive) + return 1; +- if (!synth->alive && wait_for_xmitr() > 0) { ++ if (!synth->alive && spk_wait_for_xmitr() > 0) { + /* restart */ + synth->alive = 1; + synth_printf("%s", synth->init); +@@ -192,20 +192,20 @@ void synth_start(void) + synth_buffer_clear(); + return; + } +- trigger_time = get_var(TRIGGER); ++ trigger_time = spk_get_var(TRIGGER); + if (!timer_pending(&thread_timer)) + mod_timer(&thread_timer, jiffies + + msecs_to_jiffies(trigger_time->u.n.value)); + } + +-void do_flush(void) ++void spk_do_flush(void) + { + speakup_info.flushing = 1; + synth_buffer_clear(); + if (synth->alive) { +- if (pitch_shift) { +- synth_printf("%s", pitch_buff); +- pitch_shift = 0; ++ if (spk_pitch_shift) { ++ synth_printf("%s", spk_pitch_buff); ++ spk_pitch_shift = 0; + } + } + wake_up_interruptible_all(&speakup_event); +@@ -241,7 +241,7 @@ EXPORT_SYMBOL_GPL(synth_printf); + static int index_count; + static int sentence_count; + +-void reset_index_count(int sc) ++void spk_reset_index_count(int sc) + { + static int first = 1; + if (first) +@@ -277,7 +277,7 @@ void synth_insert_next_index(int sent_num) + } + } + +-void get_index_count(int *linecount, int *sentcount) ++void spk_get_index_count(int *linecount, int *sentcount) + { + int ind = synth->get_index(); + if (ind) { +@@ -384,7 +384,7 @@ static int do_synth_init(struct spk_synth *in_synth) + for (var = synth->vars; + (var->var_id >= 0) && (var->var_id < MAXVARS); var++) + speakup_register_var(var); +- if (!quiet_boot) ++ if (!spk_quiet_boot) + synth_printf("%s found\n", synth->long_name); + if (synth->attributes.name + && sysfs_create_group(speakup_kobj, &(synth->attributes)) < 0) +@@ -412,7 +412,7 @@ void synth_release(void) + sysfs_remove_group(speakup_kobj, &(synth->attributes)); + for (var = synth->vars; var->var_id != MAXVARS; var++) + speakup_unregister_var(var->var_id); +- stop_serial_interrupt(); ++ spk_stop_serial_interrupt(); + synth->release(); + synth = NULL; + } +@@ -460,4 +460,4 @@ void synth_remove(struct spk_synth *in_synth) + } + EXPORT_SYMBOL_GPL(synth_remove); + +-short punc_masks[] = { 0, SOME, MOST, PUNC, PUNC|B_SYM }; ++short spk_punc_masks[] = { 0, SOME, MOST, PUNC, PUNC|B_SYM }; +diff --git a/drivers/staging/speakup/thread.c b/drivers/staging/speakup/thread.c +index 103c5c81ee85..42fa660a7e0d 100644 +--- a/drivers/staging/speakup/thread.c ++++ b/drivers/staging/speakup/thread.c +@@ -23,8 +23,8 @@ int speakup_thread(void *data) + DEFINE_WAIT(wait); + while (1) { + spk_lock(flags); +- our_sound = unprocessed_sound; +- unprocessed_sound.active = 0; ++ our_sound = spk_unprocessed_sound; ++ spk_unprocessed_sound.active = 0; + prepare_to_wait(&speakup_event, &wait, + TASK_INTERRUPTIBLE); + should_break = kthread_should_stop() || +diff --git a/drivers/staging/speakup/varhandlers.c b/drivers/staging/speakup/varhandlers.c +index ab7de9389dd6..f8c1e457d389 100644 +--- a/drivers/staging/speakup/varhandlers.c ++++ b/drivers/staging/speakup/varhandlers.c +@@ -16,24 +16,24 @@ static struct st_var_header var_headers[] = { + { "ex_num", EXNUMBER, VAR_PROC, NULL, NULL }, + { "characters", CHARS, VAR_PROC, NULL, NULL }, + { "synth_direct", SYNTH_DIRECT, VAR_PROC, NULL, NULL }, +- { "caps_start", CAPS_START, VAR_STRING, str_caps_start, NULL }, +- { "caps_stop", CAPS_STOP, VAR_STRING, str_caps_stop, NULL }, ++ { "caps_start", CAPS_START, VAR_STRING, spk_str_caps_start, NULL }, ++ { "caps_stop", CAPS_STOP, VAR_STRING, spk_str_caps_stop, NULL }, + { "delay_time", DELAY, VAR_TIME, NULL, NULL }, + { "trigger_time", TRIGGER, VAR_TIME, NULL, NULL }, + { "jiffy_delta", JIFFY, VAR_TIME, NULL, NULL }, + { "full_time", FULL, VAR_TIME, NULL, NULL }, +- { "spell_delay", SPELL_DELAY, VAR_NUM, &spell_delay, NULL }, +- { "bleeps", BLEEPS, VAR_NUM, &bleeps, NULL }, +- { "attrib_bleep", ATTRIB_BLEEP, VAR_NUM, &attrib_bleep, NULL }, +- { "bleep_time", BLEEP_TIME, VAR_TIME, &bleep_time, NULL }, ++ { "spell_delay", SPELL_DELAY, VAR_NUM, &spk_spell_delay, NULL }, ++ { "bleeps", BLEEPS, VAR_NUM, &spk_bleeps, NULL }, ++ { "attrib_bleep", ATTRIB_BLEEP, VAR_NUM, &spk_attrib_bleep, NULL }, ++ { "bleep_time", BLEEP_TIME, VAR_TIME, &spk_bleep_time, NULL }, + { "cursor_time", CURSOR_TIME, VAR_TIME, NULL, NULL }, +- { "punc_level", PUNC_LEVEL, VAR_NUM, &punc_level, NULL }, +- { "reading_punc", READING_PUNC, VAR_NUM, &reading_punc, NULL }, +- { "say_control", SAY_CONTROL, VAR_NUM, &say_ctrl, NULL }, +- { "say_word_ctl", SAY_WORD_CTL, VAR_NUM, &say_word_ctl, NULL }, +- { "no_interrupt", NO_INTERRUPT, VAR_NUM, &no_intr, NULL }, +- { "key_echo", KEY_ECHO, VAR_NUM, &key_echo, NULL }, +- { "bell_pos", BELL_POS, VAR_NUM, &bell_pos, NULL }, ++ { "punc_level", PUNC_LEVEL, VAR_NUM, &spk_punc_level, NULL }, ++ { "reading_punc", READING_PUNC, VAR_NUM, &spk_reading_punc, NULL }, ++ { "say_control", SAY_CONTROL, VAR_NUM, &spk_say_ctrl, NULL }, ++ { "say_word_ctl", SAY_WORD_CTL, VAR_NUM, &spk_say_word_ctl, NULL }, ++ { "no_interrupt", NO_INTERRUPT, VAR_NUM, &spk_no_intr, NULL }, ++ { "key_echo", KEY_ECHO, VAR_NUM, &spk_key_echo, NULL }, ++ { "bell_pos", BELL_POS, VAR_NUM, &spk_bell_pos, NULL }, + { "rate", RATE, VAR_NUM, NULL, NULL }, + { "pitch", PITCH, VAR_NUM, NULL, NULL }, + { "vol", VOL, VAR_NUM, NULL, NULL }, +@@ -58,7 +58,7 @@ static struct punc_var_t punc_vars[] = { + { -1, -1 }, + }; + +-int chartab_get_value(char *keyword) ++int spk_chartab_get_value(char *keyword) + { + int value = 0; + +@@ -103,11 +103,11 @@ void speakup_register_var(struct var_t *var) + p_header->data = var; + switch (p_header->var_type) { + case VAR_STRING: +- set_string_var(nothing, p_header, 0); ++ spk_set_string_var(nothing, p_header, 0); + break; + case VAR_NUM: + case VAR_TIME: +- set_num_var(0, p_header, E_DEFAULT); ++ spk_set_num_var(0, p_header, E_DEFAULT); + break; + default: + break; +@@ -123,7 +123,7 @@ void speakup_unregister_var(enum var_id_t var_id) + p_header->data = NULL; + } + +-struct st_var_header *get_var_header(enum var_id_t var_id) ++struct st_var_header *spk_get_var_header(enum var_id_t var_id) + { + struct st_var_header *p_header; + if (var_id < 0 || var_id >= MAXVARS) +@@ -134,7 +134,7 @@ struct st_var_header *get_var_header(enum var_id_t var_id) + return p_header; + } + +-struct st_var_header *var_header_by_name(const char *name) ++struct st_var_header *spk_var_header_by_name(const char *name) + { + int i; + struct st_var_header *where = NULL; +@@ -151,15 +151,15 @@ struct st_var_header *var_header_by_name(const char *name) + return where; + } + +-struct var_t *get_var(enum var_id_t var_id) ++struct var_t *spk_get_var(enum var_id_t var_id) + { + BUG_ON(var_id < 0 || var_id >= MAXVARS); + BUG_ON(!var_ptrs[var_id]); + return var_ptrs[var_id]->data; + } +-EXPORT_SYMBOL_GPL(get_var); ++EXPORT_SYMBOL_GPL(spk_get_var); + +-struct punc_var_t *get_punc_var(enum var_id_t var_id) ++struct punc_var_t *spk_get_punc_var(enum var_id_t var_id) + { + struct punc_var_t *rv = NULL; + struct punc_var_t *where; +@@ -175,7 +175,7 @@ struct punc_var_t *get_punc_var(enum var_id_t var_id) + } + + /* handlers for setting vars */ +-int set_num_var(int input, struct st_var_header *var, int how) ++int spk_set_num_var(int input, struct st_var_header *var, int how) + { + int val; + short ret = 0; +@@ -217,7 +217,7 @@ int set_num_var(int input, struct st_var_header *var, int how) + if (p_val != NULL) + *p_val = val; + if (var->var_id == PUNC_LEVEL) { +- punc_mask = punc_masks[val]; ++ spk_punc_mask = spk_punc_masks[val]; + return ret; + } + if (var_data->u.n.multiplier != 0) +@@ -232,7 +232,7 @@ int set_num_var(int input, struct st_var_header *var, int how) + if (!var_data->u.n.synth_fmt) + return ret; + if (var->var_id == PITCH) +- cp = pitch_buff; ++ cp = spk_pitch_buff; + else + cp = buf; + if (!var_data->u.n.out_str) +@@ -244,7 +244,7 @@ int set_num_var(int input, struct st_var_header *var, int how) + return ret; + } + +-int set_string_var(const char *page, struct st_var_header *var, int len) ++int spk_set_string_var(const char *page, struct st_var_header *var, int len) + { + int ret = 0; + struct var_t *var_data = var->data; +@@ -267,21 +267,21 @@ int set_string_var(const char *page, struct st_var_header *var, int len) + return ret; + } + +-/* set_mask_bits sets or clears the punc/delim/repeat bits, ++/* spk_set_mask_bits sets or clears the punc/delim/repeat bits, + * if input is null uses the defaults. + * values for how: 0 clears bits of chars supplied, + * 1 clears allk, 2 sets bits for chars */ +-int set_mask_bits(const char *input, const int which, const int how) ++int spk_set_mask_bits(const char *input, const int which, const int how) + { + u_char *cp; +- short mask = punc_info[which].mask; ++ short mask = spk_punc_info[which].mask; + if (how&1) { +- for (cp = (u_char *)punc_info[3].value; *cp; cp++) ++ for (cp = (u_char *)spk_punc_info[3].value; *cp; cp++) + spk_chartab[*cp] &= ~mask; + } + cp = (u_char *)input; + if (cp == 0) +- cp = punc_info[which].value; ++ cp = spk_punc_info[which].value; + else { + for ( ; *cp; cp++) { + if (*cp < SPACE) +@@ -308,7 +308,7 @@ int set_mask_bits(const char *input, const int which, const int how) + return 0; + } + +-char *strlwr(char *s) ++char *spk_strlwr(char *s) + { + char *p; + if (s == NULL) +@@ -341,7 +341,7 @@ char *speakup_s2i(char *start, int *dest) + return start; + } + +-char *s2uchar(char *start, char *dest) ++char *spk_s2uchar(char *start, char *dest) + { + int val = 0; + while (*start && *start <= SPACE) +@@ -357,7 +357,7 @@ char *s2uchar(char *start, char *dest) + return start; + } + +-char *xlate(char *s) ++char *spk_xlate(char *s) + { + static const char finds[] = "nrtvafe"; + static const char subs[] = "\n\r\t\013\001\014\033"; +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index 25264c4d390f..5b6dcba304b1 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + + #include "ext4_jbd2.h" + #include "xattr.h" +@@ -3580,18 +3581,20 @@ int ext4_get_inode_loc(struct inode *inode, struct ext4_iloc *iloc) + void ext4_set_inode_flags(struct inode *inode) + { + unsigned int flags = EXT4_I(inode)->i_flags; ++ unsigned int new_fl = 0; + +- inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC); + if (flags & EXT4_SYNC_FL) +- inode->i_flags |= S_SYNC; ++ new_fl |= S_SYNC; + if (flags & EXT4_APPEND_FL) +- inode->i_flags |= S_APPEND; ++ new_fl |= S_APPEND; + if (flags & EXT4_IMMUTABLE_FL) +- inode->i_flags |= S_IMMUTABLE; ++ new_fl |= S_IMMUTABLE; + if (flags & EXT4_NOATIME_FL) +- inode->i_flags |= S_NOATIME; ++ new_fl |= S_NOATIME; + if (flags & EXT4_DIRSYNC_FL) +- inode->i_flags |= S_DIRSYNC; ++ new_fl |= S_DIRSYNC; ++ set_mask_bits(&inode->i_flags, ++ S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC, new_fl); + } + + /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */ +diff --git a/include/linux/bitops.h b/include/linux/bitops.h +index a3b6b82108b9..c1dde8e00d25 100644 +--- a/include/linux/bitops.h ++++ b/include/linux/bitops.h +@@ -185,6 +185,21 @@ static inline unsigned long __ffs64(u64 word) + + #ifdef __KERNEL__ + ++#ifndef set_mask_bits ++#define set_mask_bits(ptr, _mask, _bits) \ ++({ \ ++ const typeof(*ptr) mask = (_mask), bits = (_bits); \ ++ typeof(*ptr) old, new; \ ++ \ ++ do { \ ++ old = ACCESS_ONCE(*ptr); \ ++ new = (old & ~mask) | bits; \ ++ } while (cmpxchg(ptr, old, new) != old); \ ++ \ ++ new; \ ++}) ++#endif ++ + #ifndef find_last_bit + /** + * find_last_bit - find the last set bit in a memory region +diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c +index 24fdce256cb0..31dbf0050768 100644 +--- a/net/netfilter/nf_conntrack_proto_dccp.c ++++ b/net/netfilter/nf_conntrack_proto_dccp.c +@@ -431,7 +431,7 @@ static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb, + const char *msg; + u_int8_t state; + +- dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh); ++ dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh); + BUG_ON(dh == NULL); + + state = dccp_state_table[CT_DCCP_ROLE_CLIENT][dh->dccph_type][CT_DCCP_NONE]; +@@ -488,7 +488,7 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb, + u_int8_t type, old_state, new_state; + enum ct_dccp_roles role; + +- dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh); ++ dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh); + BUG_ON(dh == NULL); + type = dh->dccph_type; + +@@ -579,7 +579,7 @@ static int dccp_error(struct net *net, struct nf_conn *tmpl, + unsigned int cscov; + const char *msg; + +- dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh); ++ dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh); + if (dh == NULL) { + msg = "nf_ct_dccp: short packet "; + goto out_invalid; diff --git a/patch/kernel/sun8i-default/0001-patch-3.4.86-87.patch b/patch/kernel/sun8i-default/0001-patch-3.4.86-87.patch new file mode 100644 index 000000000..3f689cba7 --- /dev/null +++ b/patch/kernel/sun8i-default/0001-patch-3.4.86-87.patch @@ -0,0 +1,5283 @@ +diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt +index ab22fe6e73ab..e39a0c0d6daf 100644 +--- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt ++++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt +@@ -10,8 +10,8 @@ Required properties: + + Optional properties: + - fsl,card-wired : Indicate the card is wired to host permanently +-- fsl,cd-internal : Indicate to use controller internal card detection +-- fsl,wp-internal : Indicate to use controller internal write protection ++- fsl,cd-controller : Indicate to use controller internal card detection ++- fsl,wp-controller : Indicate to use controller internal write protection + - cd-gpios : Specify GPIOs for card detection + - wp-gpios : Specify GPIOs for write protection + +@@ -21,8 +21,8 @@ esdhc@70004000 { + compatible = "fsl,imx51-esdhc"; + reg = <0x70004000 0x4000>; + interrupts = <1>; +- fsl,cd-internal; +- fsl,wp-internal; ++ fsl,cd-controller; ++ fsl,wp-controller; + }; + + esdhc@70008000 { +diff --git a/Documentation/hwmon/coretemp b/Documentation/hwmon/coretemp +index 84d46c0c71a3..eb5502e4af6c 100644 +--- a/Documentation/hwmon/coretemp ++++ b/Documentation/hwmon/coretemp +@@ -6,7 +6,9 @@ Supported chips: + Prefix: 'coretemp' + CPUID: family 0x6, models 0xe (Pentium M DC), 0xf (Core 2 DC 65nm), + 0x16 (Core 2 SC 65nm), 0x17 (Penryn 45nm), +- 0x1a (Nehalem), 0x1c (Atom), 0x1e (Lynnfield) ++ 0x1a (Nehalem), 0x1c (Atom), 0x1e (Lynnfield), ++ 0x26 (Tunnel Creek Atom), 0x27 (Medfield Atom), ++ 0x36 (Cedar Trail Atom) + Datasheet: Intel 64 and IA-32 Architectures Software Developer's Manual + Volume 3A: System Programming Guide + http://softwarecommunity.intel.com/Wiki/Mobility/720.htm +@@ -65,6 +67,11 @@ Process Processor TjMax(C) + U3400 105 + P4505/P4500 90 + ++32nm Atom Processors ++ Z2460 90 ++ D2700/2550/2500 100 ++ N2850/2800/2650/2600 100 ++ + 45nm Xeon Processors 5400 Quad-Core + X5492, X5482, X5472, X5470, X5460, X5450 85 + E5472, E5462, E5450/40/30/20/10/05 85 +@@ -85,6 +92,9 @@ Process Processor TjMax(C) + N475/470/455/450 100 + N280/270 90 + 330/230 125 ++ E680/660/640/620 90 ++ E680T/660T/640T/620T 110 ++ CE4170/4150/4110 110 + + 45nm Core2 Processors + Solo ULV SU3500/3300 100 +diff --git a/Makefile b/Makefile +index 4958e39a9d9c..8f45901dd370 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 4 +-SUBLEVEL = 86 ++SUBLEVEL = 87 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig +index 7fe19a38ba17..eeba63dede9c 100644 +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -1,7 +1,6 @@ + config ARM + bool + default y +- select HAVE_AOUT + select HAVE_DMA_API_DEBUG + select HAVE_IDE if PCI || ISA || PCMCIA + select HAVE_MEMBLOCK +diff --git a/arch/arm/boot/compressed/head-sa1100.S b/arch/arm/boot/compressed/head-sa1100.S +index 6179d94dd5c6..3115e313d9f6 100644 +--- a/arch/arm/boot/compressed/head-sa1100.S ++++ b/arch/arm/boot/compressed/head-sa1100.S +@@ -11,6 +11,7 @@ + #include + + .section ".start", "ax" ++ .arch armv4 + + __SA1100_start: + +diff --git a/arch/arm/boot/compressed/head-shark.S b/arch/arm/boot/compressed/head-shark.S +index 089c560e07f1..92b56897ed64 100644 +--- a/arch/arm/boot/compressed/head-shark.S ++++ b/arch/arm/boot/compressed/head-shark.S +@@ -18,6 +18,7 @@ + + .section ".start", "ax" + ++ .arch armv4 + b __beginning + + __ofw_data: .long 0 @ the number of memory blocks +diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S +index 87278fc80d9f..2b844dad5e93 100644 +--- a/arch/arm/boot/compressed/head.S ++++ b/arch/arm/boot/compressed/head.S +@@ -10,6 +10,7 @@ + */ + #include + ++ .arch armv7-a + /* + * Debugging stuff + * +diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts +index 9949e6060dee..6b34b23dbfbc 100644 +--- a/arch/arm/boot/dts/imx51-babbage.dts ++++ b/arch/arm/boot/dts/imx51-babbage.dts +@@ -29,8 +29,8 @@ + aips@70000000 { /* aips-1 */ + spba@70000000 { + esdhc@70004000 { /* ESDHC1 */ +- fsl,cd-internal; +- fsl,wp-internal; ++ fsl,cd-controller; ++ fsl,wp-controller; + status = "okay"; + }; + +diff --git a/arch/arm/include/asm/a.out-core.h b/arch/arm/include/asm/a.out-core.h +deleted file mode 100644 +index 92f10cb5c70c..000000000000 +--- a/arch/arm/include/asm/a.out-core.h ++++ /dev/null +@@ -1,45 +0,0 @@ +-/* a.out coredump register dumper +- * +- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. +- * Written by David Howells (dhowells@redhat.com) +- * +- * This program is free software; you can redistribute it and/or +- * modify it under the terms of the GNU General Public Licence +- * as published by the Free Software Foundation; either version +- * 2 of the Licence, or (at your option) any later version. +- */ +- +-#ifndef _ASM_A_OUT_CORE_H +-#define _ASM_A_OUT_CORE_H +- +-#ifdef __KERNEL__ +- +-#include +-#include +- +-/* +- * fill in the user structure for an a.out core dump +- */ +-static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump) +-{ +- struct task_struct *tsk = current; +- +- dump->magic = CMAGIC; +- dump->start_code = tsk->mm->start_code; +- dump->start_stack = regs->ARM_sp & ~(PAGE_SIZE - 1); +- +- dump->u_tsize = (tsk->mm->end_code - tsk->mm->start_code) >> PAGE_SHIFT; +- dump->u_dsize = (tsk->mm->brk - tsk->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT; +- dump->u_ssize = 0; +- +- memset(dump->u_debugreg, 0, sizeof(dump->u_debugreg)); +- +- if (dump->start_stack < 0x04000000) +- dump->u_ssize = (0x04000000 - dump->start_stack) >> PAGE_SHIFT; +- +- dump->regs = *regs; +- dump->u_fpvalid = dump_fpu (regs, &dump->u_fp); +-} +- +-#endif /* __KERNEL__ */ +-#endif /* _ASM_A_OUT_CORE_H */ +diff --git a/arch/arm/include/asm/a.out.h b/arch/arm/include/asm/a.out.h +deleted file mode 100644 +index 083894b2e3bc..000000000000 +--- a/arch/arm/include/asm/a.out.h ++++ /dev/null +@@ -1,34 +0,0 @@ +-#ifndef __ARM_A_OUT_H__ +-#define __ARM_A_OUT_H__ +- +-#include +-#include +- +-struct exec +-{ +- __u32 a_info; /* Use macros N_MAGIC, etc for access */ +- __u32 a_text; /* length of text, in bytes */ +- __u32 a_data; /* length of data, in bytes */ +- __u32 a_bss; /* length of uninitialized data area for file, in bytes */ +- __u32 a_syms; /* length of symbol table data in file, in bytes */ +- __u32 a_entry; /* start address */ +- __u32 a_trsize; /* length of relocation info for text, in bytes */ +- __u32 a_drsize; /* length of relocation info for data, in bytes */ +-}; +- +-/* +- * This is always the same +- */ +-#define N_TXTADDR(a) (0x00008000) +- +-#define N_TRSIZE(a) ((a).a_trsize) +-#define N_DRSIZE(a) ((a).a_drsize) +-#define N_SYMSIZE(a) ((a).a_syms) +- +-#define M_ARM 103 +- +-#ifndef LIBRARY_START_TEXT +-#define LIBRARY_START_TEXT (0x00c00000) +-#endif +- +-#endif /* __A_OUT_GNU_H__ */ +diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h +index 5ac8d3d3e025..50dad6a69c76 100644 +--- a/arch/arm/include/asm/processor.h ++++ b/arch/arm/include/asm/processor.h +@@ -54,7 +54,6 @@ struct thread_struct { + + #define start_thread(regs,pc,sp) \ + ({ \ +- unsigned long *stack = (unsigned long *)sp; \ + memset(regs->uregs, 0, sizeof(regs->uregs)); \ + if (current->personality & ADDR_LIMIT_32BIT) \ + regs->ARM_cpsr = USR_MODE; \ +@@ -65,9 +64,6 @@ struct thread_struct { + regs->ARM_cpsr |= PSR_ENDSTATE; \ + regs->ARM_pc = pc & ~1; /* pc */ \ + regs->ARM_sp = sp; /* sp */ \ +- regs->ARM_r2 = stack[2]; /* r2 (envp) */ \ +- regs->ARM_r1 = stack[1]; /* r1 (argv) */ \ +- regs->ARM_r0 = stack[0]; /* r0 (argc) */ \ + nommu_start_thread(regs); \ + }) + +diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S +index 3bf0c7f8b043..72a63f1e9320 100644 +--- a/arch/arm/kernel/head.S ++++ b/arch/arm/kernel/head.S +@@ -254,6 +254,7 @@ __create_page_tables: + /* + * Then map boot params address in r2 or the first 1MB (2MB with LPAE) + * of ram if boot params address is not specified. ++ * We map 2 sections in case the ATAGs/DTB crosses a section boundary. + */ + mov r0, r2, lsr #SECTION_SHIFT + movs r0, r0, lsl #SECTION_SHIFT +@@ -262,6 +263,8 @@ __create_page_tables: + add r3, r3, #PAGE_OFFSET + add r3, r4, r3, lsr #(SECTION_SHIFT - PMD_ORDER) + orr r6, r7, r0 ++ str r6, [r3], #1 << PMD_ORDER ++ add r6, r6, #1 << SECTION_SHIFT + str r6, [r3] + + #ifdef CONFIG_DEBUG_LL +diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c +index 8200deaa14f6..140c817b9bf9 100644 +--- a/arch/arm/kernel/topology.c ++++ b/arch/arm/kernel/topology.c +@@ -13,6 +13,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -42,6 +43,7 @@ + #define MPIDR_LEVEL2_SHIFT 16 + + struct cputopo_arm cpu_topology[NR_CPUS]; ++EXPORT_SYMBOL_GPL(cpu_topology); + + const struct cpumask *cpu_coregroup_mask(int cpu) + { +diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c +index bda7aca04ca0..18f9e710dc50 100644 +--- a/arch/arm/mach-dove/common.c ++++ b/arch/arm/mach-dove/common.c +@@ -90,7 +90,7 @@ void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data) + { + orion_ge00_init(eth_data, + DOVE_GE00_PHYS_BASE, IRQ_DOVE_GE00_SUM, +- 0, get_tclk()); ++ 0, get_tclk(), 1600); + } + + /***************************************************************************** +diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c +index 3e6aaa6361da..909e866a6872 100644 +--- a/arch/arm/mach-footbridge/common.c ++++ b/arch/arm/mach-footbridge/common.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include