diff --git a/debian/changelog b/debian/changelog index 04100dba1..cdf765f9f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -11,6 +11,9 @@ linux-2.6 (2.6.32-3) UNRELEASED; urgency=high [ Ben Hutchings ] * sfc: Apply changes from 2.6.33-rc1 adding support for SFC9000 family + * Add stable release 2.6.32.2: + - KVM: x86 emulator: limit instructions to 15 bytes (CVE-2009-4031) + - hfs: fix a potential buffer overflow (CVE-2009-4020) -- Martin Michlmayr Fri, 18 Dec 2009 15:34:01 +0000 diff --git a/debian/patches/bugfix/all/stable/2.6.32.2.patch b/debian/patches/bugfix/all/stable/2.6.32.2.patch new file mode 100644 index 000000000..c57398fc3 --- /dev/null +++ b/debian/patches/bugfix/all/stable/2.6.32.2.patch @@ -0,0 +1,5447 @@ +diff --git a/Documentation/Changes b/Documentation/Changes +index 6d0f1ef..f08b313 100644 +--- a/Documentation/Changes ++++ b/Documentation/Changes +@@ -49,6 +49,8 @@ o oprofile 0.9 # oprofiled --version + o udev 081 # udevinfo -V + o grub 0.93 # grub --version + o mcelog 0.6 ++o iptables 1.4.1 # iptables -V ++ + + Kernel compilation + ================== +diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt +index 9107b38..5bc4eaa 100644 +--- a/Documentation/kernel-parameters.txt ++++ b/Documentation/kernel-parameters.txt +@@ -2645,6 +2645,8 @@ and is between 256 and 4096 characters. It is defined in the file + to a common usb-storage quirk flag as follows: + a = SANE_SENSE (collect more than 18 bytes + of sense data); ++ b = BAD_SENSE (don't collect more than 18 ++ bytes of sense data); + c = FIX_CAPACITY (decrease the reported + device capacity by one sector); + h = CAPACITY_HEURISTICS (decrease the +diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt +index 3f61825..90e85a8 100644 +--- a/Documentation/video4linux/gspca.txt ++++ b/Documentation/video4linux/gspca.txt +@@ -37,6 +37,7 @@ ov519 041e:405f Creative Live! VISTA VF0330 + ov519 041e:4060 Creative Live! VISTA VF0350 + ov519 041e:4061 Creative Live! VISTA VF0400 + ov519 041e:4064 Creative Live! VISTA VF0420 ++ov519 041e:4067 Creative Live! Cam Video IM (VF0350) + ov519 041e:4068 Creative Live! VISTA VF0470 + spca561 0458:7004 Genius VideoCAM Express V2 + sunplus 0458:7006 Genius Dsc 1.3 Smart +diff --git a/MAINTAINERS b/MAINTAINERS +index 4f96ac8..c57d396 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -5594,9 +5594,11 @@ S: Maintained + F: drivers/net/wireless/rndis_wlan.c + + USB XHCI DRIVER +-M: Sarah Sharp ++M: Sarah Sharp + L: linux-usb@vger.kernel.org + S: Supported ++F: drivers/usb/host/xhci* ++F: drivers/usb/host/pci-quirks* + + USB ZC0301 DRIVER + M: Luca Risolia +diff --git a/Makefile b/Makefile +index d0d7e9c..23803ce 100644 +diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c +index aec7f42..86a8732 100644 +--- a/arch/arm/mach-pxa/em-x270.c ++++ b/arch/arm/mach-pxa/em-x270.c +@@ -497,16 +497,15 @@ static int em_x270_usb_hub_init(void) + goto err_free_vbus_gpio; + + /* USB Hub power-on and reset */ +- gpio_direction_output(usb_hub_reset, 0); ++ gpio_direction_output(usb_hub_reset, 1); ++ gpio_direction_output(GPIO9_USB_VBUS_EN, 0); + regulator_enable(em_x270_usb_ldo); +- gpio_set_value(usb_hub_reset, 1); + gpio_set_value(usb_hub_reset, 0); ++ gpio_set_value(usb_hub_reset, 1); + regulator_disable(em_x270_usb_ldo); + regulator_enable(em_x270_usb_ldo); +- gpio_set_value(usb_hub_reset, 1); +- +- /* enable VBUS */ +- gpio_direction_output(GPIO9_USB_VBUS_EN, 1); ++ gpio_set_value(usb_hub_reset, 0); ++ gpio_set_value(GPIO9_USB_VBUS_EN, 1); + + return 0; + +diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h +index 0d9d16e..cc8335e 100644 +--- a/arch/ia64/include/asm/io.h ++++ b/arch/ia64/include/asm/io.h +@@ -424,6 +424,8 @@ __writeq (unsigned long val, volatile void __iomem *addr) + extern void __iomem * ioremap(unsigned long offset, unsigned long size); + extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size); + extern void iounmap (volatile void __iomem *addr); ++extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size); ++extern void early_iounmap (volatile void __iomem *addr, unsigned long size); + + /* + * String version of IO memory access ops: +diff --git a/arch/ia64/mm/ioremap.c b/arch/ia64/mm/ioremap.c +index 2a14062..3dccdd8 100644 +--- a/arch/ia64/mm/ioremap.c ++++ b/arch/ia64/mm/ioremap.c +@@ -22,6 +22,12 @@ __ioremap (unsigned long phys_addr) + } + + void __iomem * ++early_ioremap (unsigned long phys_addr, unsigned long size) ++{ ++ return __ioremap(phys_addr); ++} ++ ++void __iomem * + ioremap (unsigned long phys_addr, unsigned long size) + { + void __iomem *addr; +@@ -102,6 +108,11 @@ ioremap_nocache (unsigned long phys_addr, unsigned long size) + EXPORT_SYMBOL(ioremap_nocache); + + void ++early_iounmap (volatile void __iomem *addr, unsigned long size) ++{ ++} ++ ++void + iounmap (volatile void __iomem *addr) + { + if (REGION_NUMBER(addr) == RGN_GATE) +diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S +index 67b6916..fe46048 100644 +--- a/arch/powerpc/kernel/vector.S ++++ b/arch/powerpc/kernel/vector.S +@@ -58,7 +58,7 @@ _GLOBAL(load_up_altivec) + * all 1's + */ + mfspr r4,SPRN_VRSAVE +- cmpdi 0,r4,0 ++ cmpwi 0,r4,0 + bne+ 1f + li r4,-1 + mtspr SPRN_VRSAVE,r4 +diff --git a/arch/s390/include/asm/kvm.h b/arch/s390/include/asm/kvm.h +index 3dfcaeb..82b32a1 100644 +--- a/arch/s390/include/asm/kvm.h ++++ b/arch/s390/include/asm/kvm.h +@@ -1,6 +1,5 @@ + #ifndef __LINUX_KVM_S390_H + #define __LINUX_KVM_S390_H +- + /* + * asm-s390/kvm.h - KVM s390 specific structures and definitions + * +@@ -15,6 +14,8 @@ + */ + #include + ++#define __KVM_S390 ++ + /* for KVM_GET_REGS and KVM_SET_REGS */ + struct kvm_regs { + /* general purpose regs for s390 */ +diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S +index 6a25080..d984a2a 100644 +--- a/arch/s390/kernel/head64.S ++++ b/arch/s390/kernel/head64.S +@@ -83,6 +83,8 @@ startup_continue: + slr %r0,%r0 # set cpuid to zero + sigp %r1,%r0,0x12 # switch to esame mode + sam64 # switch to 64 bit mode ++ llgfr %r13,%r13 # clear high-order half of base reg ++ lmh %r0,%r15,.Lzero64-.LPG1(%r13) # clear high-order half + lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers + lg %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area + # move IPL device to lowcore +@@ -127,6 +129,7 @@ startup_continue: + .L4malign:.quad 0xffffffffffc00000 + .Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8 + .Lnop: .long 0x07000700 ++.Lzero64:.fill 16,4,0x0 + #ifdef CONFIG_ZFCPDUMP + .Lcurrent_cpu: + .long 0x0 +diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c +index 07ced89..ca2d312 100644 +--- a/arch/s390/kvm/kvm-s390.c ++++ b/arch/s390/kvm/kvm-s390.c +@@ -116,10 +116,16 @@ long kvm_arch_dev_ioctl(struct file *filp, + + int kvm_dev_ioctl_check_extension(long ext) + { ++ int r; ++ + switch (ext) { ++ case KVM_CAP_S390_PSW: ++ r = 1; ++ break; + default: +- return 0; ++ r = 0; + } ++ return r; + } + + /* Section: vm related */ +@@ -419,8 +425,10 @@ static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw) + vcpu_load(vcpu); + if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING) + rc = -EBUSY; +- else +- vcpu->arch.sie_block->gpsw = psw; ++ else { ++ vcpu->run->psw_mask = psw.mask; ++ vcpu->run->psw_addr = psw.addr; ++ } + vcpu_put(vcpu); + return rc; + } +@@ -508,9 +516,6 @@ rerun_vcpu: + + switch (kvm_run->exit_reason) { + case KVM_EXIT_S390_SIEIC: +- vcpu->arch.sie_block->gpsw.mask = kvm_run->s390_sieic.mask; +- vcpu->arch.sie_block->gpsw.addr = kvm_run->s390_sieic.addr; +- break; + case KVM_EXIT_UNKNOWN: + case KVM_EXIT_INTR: + case KVM_EXIT_S390_RESET: +@@ -519,6 +524,9 @@ rerun_vcpu: + BUG(); + } + ++ vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask; ++ vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr; ++ + might_fault(); + + do { +@@ -538,8 +546,6 @@ rerun_vcpu: + /* intercept cannot be handled in-kernel, prepare kvm-run */ + kvm_run->exit_reason = KVM_EXIT_S390_SIEIC; + kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode; +- kvm_run->s390_sieic.mask = vcpu->arch.sie_block->gpsw.mask; +- kvm_run->s390_sieic.addr = vcpu->arch.sie_block->gpsw.addr; + kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa; + kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb; + rc = 0; +@@ -551,6 +557,9 @@ rerun_vcpu: + rc = 0; + } + ++ kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask; ++ kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr; ++ + if (vcpu->sigset_active) + sigprocmask(SIG_SETMASK, &sigsaved, NULL); + +diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c +index 40c8c67..15ee111 100644 +--- a/arch/s390/kvm/sigp.c ++++ b/arch/s390/kvm/sigp.c +@@ -188,9 +188,9 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address, + + /* make sure that the new value is valid memory */ + address = address & 0x7fffe000u; +- if ((copy_from_guest(vcpu, &tmp, +- (u64) (address + vcpu->arch.sie_block->gmsor) , 1)) || +- (copy_from_guest(vcpu, &tmp, (u64) (address + ++ if ((copy_from_user(&tmp, (void __user *) ++ (address + vcpu->arch.sie_block->gmsor) , 1)) || ++ (copy_from_user(&tmp, (void __user *)(address + + vcpu->arch.sie_block->gmsor + PAGE_SIZE), 1))) { + *reg |= SIGP_STAT_INVALID_PARAMETER; + return 1; /* invalid parameter */ +diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile +index dfe272d..113225b 100644 +--- a/arch/sparc/Makefile ++++ b/arch/sparc/Makefile +@@ -27,6 +27,7 @@ AS := $(AS) -32 + LDFLAGS := -m elf32_sparc + CHECKFLAGS += -D__sparc__ + export BITS := 32 ++UTS_MACHINE := sparc + + #KBUILD_CFLAGS += -g -pipe -fcall-used-g5 -fcall-used-g7 + KBUILD_CFLAGS += -m32 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7 +@@ -46,6 +47,7 @@ CHECKFLAGS += -D__sparc__ -D__sparc_v9__ -D__arch64__ -m64 + + LDFLAGS := -m elf64_sparc + export BITS := 64 ++UTS_MACHINE := sparc64 + + KBUILD_CFLAGS += -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow \ + -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare \ +diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c +index cb3c72c..e0ba898 100644 +--- a/arch/sparc/kernel/ldc.c ++++ b/arch/sparc/kernel/ldc.c +@@ -1242,13 +1242,13 @@ int ldc_bind(struct ldc_channel *lp, const char *name) + snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); + + err = request_irq(lp->cfg.rx_irq, ldc_rx, +- IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED, ++ IRQF_SAMPLE_RANDOM | IRQF_DISABLED, + lp->rx_irq_name, lp); + if (err) + return err; + + err = request_irq(lp->cfg.tx_irq, ldc_tx, +- IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED, ++ IRQF_SAMPLE_RANDOM | IRQF_DISABLED, + lp->tx_irq_name, lp); + if (err) { + free_irq(lp->cfg.rx_irq, lp); +diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c +index 881947e..0a6f2d1 100644 +--- a/arch/sparc/kernel/of_device_64.c ++++ b/arch/sparc/kernel/of_device_64.c +@@ -104,9 +104,19 @@ static int of_bus_pci_map(u32 *addr, const u32 *range, + int i; + + /* Check address type match */ +- if ((addr[0] ^ range[0]) & 0x03000000) +- return -EINVAL; ++ if (!((addr[0] ^ range[0]) & 0x03000000)) ++ goto type_match; ++ ++ /* Special exception, we can map a 64-bit address into ++ * a 32-bit range. ++ */ ++ if ((addr[0] & 0x03000000) == 0x03000000 && ++ (range[0] & 0x03000000) == 0x02000000) ++ goto type_match; ++ ++ return -EINVAL; + ++type_match: + if (of_out_of_range(addr + 1, range + 1, range + na + pna, + na - 1, ns)) + return -EINVAL; +diff --git a/arch/sparc/lib/mcount.S b/arch/sparc/lib/mcount.S +index 7ce9c65..24b8b12 100644 +--- a/arch/sparc/lib/mcount.S ++++ b/arch/sparc/lib/mcount.S +@@ -64,8 +64,9 @@ mcount: + 2: sethi %hi(softirq_stack), %g3 + or %g3, %lo(softirq_stack), %g3 + ldx [%g3 + %g1], %g7 ++ sub %g7, STACK_BIAS, %g7 + cmp %sp, %g7 +- bleu,pt %xcc, 2f ++ bleu,pt %xcc, 3f + sethi %hi(THREAD_SIZE), %g3 + add %g7, %g3, %g7 + cmp %sp, %g7 +@@ -75,7 +76,7 @@ mcount: + * again, we are already trying to output the stack overflow + * message. + */ +- sethi %hi(ovstack), %g7 ! cant move to panic stack fast enough ++3: sethi %hi(ovstack), %g7 ! cant move to panic stack fast enough + or %g7, %lo(ovstack), %g7 + add %g7, OVSTACKSIZE, %g3 + sub %g3, STACK_BIAS + 192, %g3 +diff --git a/arch/x86/Makefile_32.cpu b/arch/x86/Makefile_32.cpu +index 30e9a26..1937226 100644 +--- a/arch/x86/Makefile_32.cpu ++++ b/arch/x86/Makefile_32.cpu +@@ -46,6 +46,13 @@ cflags-$(CONFIG_MGEODEGX1) += -march=pentium-mmx + # cpu entries + cflags-$(CONFIG_X86_GENERIC) += $(call tune,generic,$(call tune,i686)) + ++# Work around the pentium-mmx code generator madness of gcc4.4.x which ++# does stack alignment by generating horrible code _before_ the mcount ++# prologue (push %ebp, mov %esp, %ebp) which breaks the function graph ++# tracer assumptions. For i686, generic, core2 this is set by the ++# compiler anyway ++cflags-$(CONFIG_FUNCTION_GRAPH_TRACER) += $(call cc-option,-maccumulate-outgoing-args) ++ + # Bug fix for binutils: this option is required in order to keep + # binutils from generating NOPL instructions against our will. + ifneq ($(CONFIG_X86_P6_NOP),y) +diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h +index 5b21f0e..6e90a04 100644 +--- a/arch/x86/include/asm/irq_vectors.h ++++ b/arch/x86/include/asm/irq_vectors.h +@@ -113,7 +113,7 @@ + */ + #define LOCAL_PENDING_VECTOR 0xec + +-#define UV_BAU_MESSAGE 0xec ++#define UV_BAU_MESSAGE 0xea + + /* + * Self IPI vector for machine checks +diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h +index b7ed2c4..7c18e12 100644 +--- a/arch/x86/include/asm/kvm_emulate.h ++++ b/arch/x86/include/asm/kvm_emulate.h +@@ -129,7 +129,7 @@ struct decode_cache { + u8 seg_override; + unsigned int d; + unsigned long regs[NR_VCPU_REGS]; +- unsigned long eip; ++ unsigned long eip, eip_orig; + /* modrm */ + u8 modrm; + u8 modrm_mod; +diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h +index f1363b7..a479023 100644 +--- a/arch/x86/include/asm/mce.h ++++ b/arch/x86/include/asm/mce.h +@@ -214,5 +214,11 @@ void intel_init_thermal(struct cpuinfo_x86 *c); + + void mce_log_therm_throt_event(__u64 status); + ++#ifdef CONFIG_X86_THERMAL_VECTOR ++extern void mcheck_intel_therm_init(void); ++#else ++static inline void mcheck_intel_therm_init(void) { } ++#endif ++ + #endif /* __KERNEL__ */ + #endif /* _ASM_X86_MCE_H */ +diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c +index 59cdfa4..2e837f5 100644 +--- a/arch/x86/kernel/acpi/cstate.c ++++ b/arch/x86/kernel/acpi/cstate.c +@@ -48,7 +48,7 @@ void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags, + * P4, Core and beyond CPUs + */ + if (c->x86_vendor == X86_VENDOR_INTEL && +- (c->x86 > 0xf || (c->x86 == 6 && c->x86_model >= 14))) ++ (c->x86 > 0xf || (c->x86 == 6 && c->x86_model >= 0x0f))) + flags->bm_control = 0; + } + EXPORT_SYMBOL(acpi_processor_power_init_bm_check); +diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c +index 0285521..90b9b55 100644 +--- a/arch/x86/kernel/amd_iommu.c ++++ b/arch/x86/kernel/amd_iommu.c +@@ -2047,10 +2047,10 @@ static void prealloc_protection_domains(void) + struct pci_dev *dev = NULL; + struct dma_ops_domain *dma_dom; + struct amd_iommu *iommu; +- u16 devid; ++ u16 devid, __devid; + + while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { +- devid = calc_devid(dev->bus->number, dev->devfn); ++ __devid = devid = calc_devid(dev->bus->number, dev->devfn); + if (devid > amd_iommu_last_bdf) + continue; + devid = amd_iommu_alias_table[devid]; +@@ -2065,6 +2065,10 @@ static void prealloc_protection_domains(void) + init_unity_mappings_for_device(dma_dom, devid); + dma_dom->target_dev = devid; + ++ attach_device(iommu, &dma_dom->domain, devid); ++ if (__devid != devid) ++ attach_device(iommu, &dma_dom->domain, __devid); ++ + list_add_tail(&dma_dom->list, &iommu_pd_list); + } + } +diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c +index c20001e..e0b3130 100644 +--- a/arch/x86/kernel/amd_iommu_init.c ++++ b/arch/x86/kernel/amd_iommu_init.c +@@ -925,7 +925,7 @@ static int __init init_iommu_all(struct acpi_table_header *table) + * + ****************************************************************************/ + +-static int __init iommu_setup_msi(struct amd_iommu *iommu) ++static int iommu_setup_msi(struct amd_iommu *iommu) + { + int r; + +diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c +index 894aa97..c86dbcf 100644 +--- a/arch/x86/kernel/apic/apic.c ++++ b/arch/x86/kernel/apic/apic.c +@@ -246,7 +246,7 @@ static int modern_apic(void) + */ + static void native_apic_write_dummy(u32 reg, u32 v) + { +- WARN_ON_ONCE((cpu_has_apic || !disable_apic)); ++ WARN_ON_ONCE(cpu_has_apic && !disable_apic); + } + + static u32 native_apic_read_dummy(u32 reg) +diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c +index 804c40e..8178d03 100644 +--- a/arch/x86/kernel/cpu/intel_cacheinfo.c ++++ b/arch/x86/kernel/cpu/intel_cacheinfo.c +@@ -94,7 +94,7 @@ static const struct _cache_table __cpuinitconst cache_table[] = + { 0xd1, LVL_3, 1024 }, /* 4-way set assoc, 64 byte line size */ + { 0xd2, LVL_3, 2048 }, /* 4-way set assoc, 64 byte line size */ + { 0xd6, LVL_3, 1024 }, /* 8-way set assoc, 64 byte line size */ +- { 0xd7, LVL_3, 2038 }, /* 8-way set assoc, 64 byte line size */ ++ { 0xd7, LVL_3, 2048 }, /* 8-way set assoc, 64 byte line size */ + { 0xd8, LVL_3, 4096 }, /* 12-way set assoc, 64 byte line size */ + { 0xdc, LVL_3, 2048 }, /* 12-way set assoc, 64 byte line size */ + { 0xdd, LVL_3, 4096 }, /* 12-way set assoc, 64 byte line size */ +@@ -102,6 +102,9 @@ static const struct _cache_table __cpuinitconst cache_table[] = + { 0xe2, LVL_3, 2048 }, /* 16-way set assoc, 64 byte line size */ + { 0xe3, LVL_3, 4096 }, /* 16-way set assoc, 64 byte line size */ + { 0xe4, LVL_3, 8192 }, /* 16-way set assoc, 64 byte line size */ ++ { 0xea, LVL_3, 12288 }, /* 24-way set assoc, 64 byte line size */ ++ { 0xeb, LVL_3, 18432 }, /* 24-way set assoc, 64 byte line size */ ++ { 0xec, LVL_3, 24576 }, /* 24-way set assoc, 64 byte line size */ + { 0x00, 0, 0} + }; + +diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c +index 721a77c..0f16a2b 100644 +--- a/arch/x86/kernel/cpu/mcheck/mce.c ++++ b/arch/x86/kernel/cpu/mcheck/mce.c +@@ -1374,13 +1374,14 @@ static void mce_init_timer(void) + struct timer_list *t = &__get_cpu_var(mce_timer); + int *n = &__get_cpu_var(mce_next_interval); + ++ setup_timer(t, mcheck_timer, smp_processor_id()); ++ + if (mce_ignore_ce) + return; + + *n = check_interval * HZ; + if (!*n) + return; +- setup_timer(t, mcheck_timer, smp_processor_id()); + t->expires = round_jiffies(jiffies + *n); + add_timer_on(t, smp_processor_id()); + } +@@ -1991,9 +1992,11 @@ mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) + break; + case CPU_DOWN_FAILED: + case CPU_DOWN_FAILED_FROZEN: +- t->expires = round_jiffies(jiffies + ++ if (!mce_ignore_ce && check_interval) { ++ t->expires = round_jiffies(jiffies + + __get_cpu_var(mce_next_interval)); +- add_timer_on(t, cpu); ++ add_timer_on(t, cpu); ++ } + smp_call_function_single(cpu, mce_reenable_cpu, &action, 1); + break; + case CPU_POST_DEAD: +diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c +index b3a1dba..4fef985 100644 +--- a/arch/x86/kernel/cpu/mcheck/therm_throt.c ++++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c +@@ -49,6 +49,8 @@ static DEFINE_PER_CPU(struct thermal_state, thermal_state); + + static atomic_t therm_throt_en = ATOMIC_INIT(0); + ++static u32 lvtthmr_init __read_mostly; ++ + #ifdef CONFIG_SYSFS + #define define_therm_throt_sysdev_one_ro(_name) \ + static SYSDEV_ATTR(_name, 0444, therm_throt_sysdev_show_##_name, NULL) +@@ -254,6 +256,18 @@ asmlinkage void smp_thermal_interrupt(struct pt_regs *regs) + ack_APIC_irq(); + } + ++void __init mcheck_intel_therm_init(void) ++{ ++ /* ++ * This function is only called on boot CPU. Save the init thermal ++ * LVT value on BSP and use that value to restore APs' thermal LVT ++ * entry BIOS programmed later ++ */ ++ if (cpu_has(&boot_cpu_data, X86_FEATURE_ACPI) && ++ cpu_has(&boot_cpu_data, X86_FEATURE_ACC)) ++ lvtthmr_init = apic_read(APIC_LVTTHMR); ++} ++ + void intel_init_thermal(struct cpuinfo_x86 *c) + { + unsigned int cpu = smp_processor_id(); +@@ -270,7 +284,20 @@ void intel_init_thermal(struct cpuinfo_x86 *c) + * since it might be delivered via SMI already: + */ + rdmsr(MSR_IA32_MISC_ENABLE, l, h); +- h = apic_read(APIC_LVTTHMR); ++ ++ /* ++ * The initial value of thermal LVT entries on all APs always reads ++ * 0x10000 because APs are woken up by BSP issuing INIT-SIPI-SIPI ++ * sequence to them and LVT registers are reset to 0s except for ++ * the mask bits which are set to 1s when APs receive INIT IPI. ++ * Always restore the value that BIOS has programmed on AP based on ++ * BSP's info we saved since BIOS is always setting the same value ++ * for all threads/cores ++ */ ++ apic_write(APIC_LVTTHMR, lvtthmr_init); ++ ++ h = lvtthmr_init; ++ + if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) { + printk(KERN_DEBUG + "CPU%d: Thermal monitoring handled by SMI\n", cpu); +diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c +index fab786f..898df97 100644 +--- a/arch/x86/kernel/cpu/perfctr-watchdog.c ++++ b/arch/x86/kernel/cpu/perfctr-watchdog.c +@@ -712,7 +712,7 @@ static void probe_nmi_watchdog(void) + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + if (boot_cpu_data.x86 != 6 && boot_cpu_data.x86 != 15 && +- boot_cpu_data.x86 != 16) ++ boot_cpu_data.x86 != 16 && boot_cpu_data.x86 != 17) + return; + wd_ops = &k7_wd_ops; + break; +diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c +index 971a3be..e6ec8a2 100644 +--- a/arch/x86/kernel/pci-calgary_64.c ++++ b/arch/x86/kernel/pci-calgary_64.c +@@ -318,13 +318,15 @@ static inline struct iommu_table *find_iommu_table(struct device *dev) + + pdev = to_pci_dev(dev); + ++ /* search up the device tree for an iommu */ + pbus = pdev->bus; +- +- /* is the device behind a bridge? Look for the root bus */ +- while (pbus->parent) ++ do { ++ tbl = pci_iommu(pbus); ++ if (tbl && tbl->it_busno == pbus->number) ++ break; ++ tbl = NULL; + pbus = pbus->parent; +- +- tbl = pci_iommu(pbus); ++ } while (pbus); + + BUG_ON(tbl && (tbl->it_busno != pbus->number)); + +diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c +index a6e804d..6ac3931 100644 +--- a/arch/x86/kernel/pci-dma.c ++++ b/arch/x86/kernel/pci-dma.c +@@ -214,7 +214,7 @@ static __init int iommu_setup(char *p) + if (!strncmp(p, "allowdac", 8)) + forbid_dac = 0; + if (!strncmp(p, "nodac", 5)) +- forbid_dac = -1; ++ forbid_dac = 1; + if (!strncmp(p, "usedac", 6)) { + forbid_dac = -1; + return 1; +diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c +index a7f1b64..fcc0b5c 100644 +--- a/arch/x86/kernel/pci-gart_64.c ++++ b/arch/x86/kernel/pci-gart_64.c +@@ -856,7 +856,7 @@ void __init gart_parse_options(char *p) + #endif + if (isdigit(*p) && get_option(&p, &arg)) + iommu_size = arg; +- if (!strncmp(p, "fullflush", 8)) ++ if (!strncmp(p, "fullflush", 9)) + iommu_fullflush = 1; + if (!strncmp(p, "nofullflush", 11)) + iommu_fullflush = 0; +diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c +index f930787..6caf260 100644 +--- a/arch/x86/kernel/reboot.c ++++ b/arch/x86/kernel/reboot.c +@@ -259,6 +259,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "SBC-FITPC2"), + }, + }, ++ { /* Handle problems with rebooting on ASUS P4S800 */ ++ .callback = set_bios_reboot, ++ .ident = "ASUS P4S800", ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), ++ DMI_MATCH(DMI_BOARD_NAME, "P4S800"), ++ }, ++ }, + { } + }; + +diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c +index 2a34f9c..51aa5b2 100644 +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -109,6 +109,7 @@ + #ifdef CONFIG_X86_64 + #include + #endif ++#include + + /* + * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries. +@@ -1031,6 +1032,8 @@ void __init setup_arch(char **cmdline_p) + #endif + #endif + x86_init.oem.banner(); ++ ++ mcheck_intel_therm_init(); + } + + #ifdef CONFIG_X86_32 +diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c +index 1740c85..364d015 100644 +--- a/arch/x86/kernel/tlb_uv.c ++++ b/arch/x86/kernel/tlb_uv.c +@@ -817,10 +817,8 @@ static int __init uv_init_blade(int blade) + */ + apicid = blade_to_first_apicid(blade); + pa = uv_read_global_mmr64(pnode, UVH_BAU_DATA_CONFIG); +- if ((pa & 0xff) != UV_BAU_MESSAGE) { +- uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG, ++ uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG, + ((apicid << 32) | UV_BAU_MESSAGE)); +- } + return 0; + } + +diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c +index 1be5cd6..e02dbb6 100644 +--- a/arch/x86/kvm/emulate.c ++++ b/arch/x86/kvm/emulate.c +@@ -613,6 +613,9 @@ static int do_insn_fetch(struct x86_emulate_ctxt *ctxt, + { + int rc = 0; + ++ /* x86 instructions are limited to 15 bytes. */ ++ if (eip + size - ctxt->decode.eip_orig > 15) ++ return X86EMUL_UNHANDLEABLE; + eip += ctxt->cs_base; + while (size--) { + rc = do_fetch_insn_byte(ctxt, ops, eip++, dest++); +@@ -871,7 +874,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) + /* Shadow copy of register state. Committed on successful emulation. */ + + memset(c, 0, sizeof(struct decode_cache)); +- c->eip = kvm_rip_read(ctxt->vcpu); ++ c->eip = c->eip_orig = kvm_rip_read(ctxt->vcpu); + ctxt->cs_base = seg_base(ctxt, VCPU_SREG_CS); + memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); + +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index ae07d26..97b31fa 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -484,16 +484,19 @@ static inline u32 bit(int bitno) + * and KVM_SET_MSRS, and KVM_GET_MSR_INDEX_LIST. + * + * This list is modified at module load time to reflect the +- * capabilities of the host cpu. ++ * capabilities of the host cpu. This capabilities test skips MSRs that are ++ * kvm-specific. Those are put in the beginning of the list. + */ ++ ++#define KVM_SAVE_MSRS_BEGIN 2 + static u32 msrs_to_save[] = { ++ MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK, + MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP, + MSR_K6_STAR, + #ifdef CONFIG_X86_64 + MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR, + #endif +- MSR_IA32_TSC, MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK, +- MSR_IA32_PERF_STATUS, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA ++ MSR_IA32_TSC, MSR_IA32_PERF_STATUS, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA + }; + + static unsigned num_msrs_to_save; +@@ -2433,7 +2436,8 @@ static void kvm_init_msr_list(void) + u32 dummy[2]; + unsigned i, j; + +- for (i = j = 0; i < ARRAY_SIZE(msrs_to_save); i++) { ++ /* skip the first msrs in the list. KVM-specific */ ++ for (i = j = KVM_SAVE_MSRS_BEGIN; i < ARRAY_SIZE(msrs_to_save); i++) { + if (rdmsr_safe(msrs_to_save[i], &dummy[0], &dummy[1]) < 0) + continue; + if (j < i) +diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c +index dfbf70e..79f9738 100644 +--- a/arch/x86/xen/enlighten.c ++++ b/arch/x86/xen/enlighten.c +@@ -138,24 +138,23 @@ static void xen_vcpu_setup(int cpu) + */ + void xen_vcpu_restore(void) + { +- if (have_vcpu_info_placement) { +- int cpu; ++ int cpu; + +- for_each_online_cpu(cpu) { +- bool other_cpu = (cpu != smp_processor_id()); ++ for_each_online_cpu(cpu) { ++ bool other_cpu = (cpu != smp_processor_id()); + +- if (other_cpu && +- HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL)) +- BUG(); ++ if (other_cpu && ++ HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL)) ++ BUG(); + +- xen_vcpu_setup(cpu); ++ xen_setup_runstate_info(cpu); + +- if (other_cpu && +- HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL)) +- BUG(); +- } ++ if (have_vcpu_info_placement) ++ xen_vcpu_setup(cpu); + +- BUG_ON(!have_vcpu_info_placement); ++ if (other_cpu && ++ HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL)) ++ BUG(); + } + } + +@@ -1182,6 +1181,8 @@ asmlinkage void __init xen_start_kernel(void) + + xen_raw_console_write("about to get started...\n"); + ++ xen_setup_runstate_info(0); ++ + /* Start the world */ + #ifdef CONFIG_X86_32 + i386_start_kernel(); +diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c +index 3bf7b1d..bf4cd6b 100644 +--- a/arch/x86/xen/mmu.c ++++ b/arch/x86/xen/mmu.c +@@ -185,7 +185,7 @@ static inline unsigned p2m_index(unsigned long pfn) + } + + /* Build the parallel p2m_top_mfn structures */ +-static void __init xen_build_mfn_list_list(void) ++void xen_build_mfn_list_list(void) + { + unsigned pfn, idx; + +diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c +index fe03eee..360f8d8 100644 +--- a/arch/x86/xen/smp.c ++++ b/arch/x86/xen/smp.c +@@ -295,6 +295,7 @@ static int __cpuinit xen_cpu_up(unsigned int cpu) + (unsigned long)task_stack_page(idle) - + KERNEL_STACK_OFFSET + THREAD_SIZE; + #endif ++ xen_setup_runstate_info(cpu); + xen_setup_timer(cpu); + xen_init_lock_cpu(cpu); + +diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c +index 95be7b4..987267f 100644 +--- a/arch/x86/xen/suspend.c ++++ b/arch/x86/xen/suspend.c +@@ -1,4 +1,5 @@ + #include ++#include + + #include + #include +@@ -27,6 +28,8 @@ void xen_pre_suspend(void) + + void xen_post_suspend(int suspend_cancelled) + { ++ xen_build_mfn_list_list(); ++ + xen_setup_shared_info(); + + if (suspend_cancelled) { +@@ -44,7 +47,19 @@ void xen_post_suspend(int suspend_cancelled) + + } + ++static void xen_vcpu_notify_restore(void *data) ++{ ++ unsigned long reason = (unsigned long)data; ++ ++ /* Boot processor notified via generic timekeeping_resume() */ ++ if ( smp_processor_id() == 0) ++ return; ++ ++ clockevents_notify(reason, NULL); ++} ++ + void xen_arch_resume(void) + { +- /* nothing */ ++ smp_call_function(xen_vcpu_notify_restore, ++ (void *)CLOCK_EVT_NOTIFY_RESUME, 1); + } +diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c +index 0a5aa44..9d1f853 100644 +--- a/arch/x86/xen/time.c ++++ b/arch/x86/xen/time.c +@@ -100,7 +100,7 @@ bool xen_vcpu_stolen(int vcpu) + return per_cpu(runstate, vcpu).state == RUNSTATE_runnable; + } + +-static void setup_runstate_info(int cpu) ++void xen_setup_runstate_info(int cpu) + { + struct vcpu_register_runstate_memory_area area; + +@@ -434,7 +434,7 @@ void xen_setup_timer(int cpu) + name = ""; + + irq = bind_virq_to_irqhandler(VIRQ_TIMER, cpu, xen_timer_interrupt, +- IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING, ++ IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING|IRQF_TIMER, + name, NULL); + + evt = &per_cpu(xen_clock_events, cpu); +@@ -442,8 +442,6 @@ void xen_setup_timer(int cpu) + + evt->cpumask = cpumask_of(cpu); + evt->irq = irq; +- +- setup_runstate_info(cpu); + } + + void xen_teardown_timer(int cpu) +@@ -494,6 +492,7 @@ __init void xen_time_init(void) + + setup_force_cpu_cap(X86_FEATURE_TSC); + ++ xen_setup_runstate_info(cpu); + xen_setup_timer(cpu); + xen_setup_cpu_clockevents(); + } +diff --git a/arch/x86/xen/xen-asm_64.S b/arch/x86/xen/xen-asm_64.S +index 02f496a..53adefd 100644 +--- a/arch/x86/xen/xen-asm_64.S ++++ b/arch/x86/xen/xen-asm_64.S +@@ -96,7 +96,7 @@ ENTRY(xen_sysret32) + pushq $__USER32_CS + pushq %rcx + +- pushq $VGCF_in_syscall ++ pushq $0 + 1: jmp hypercall_iret + ENDPATCH(xen_sysret32) + RELOC(xen_sysret32, 1b+1) +@@ -151,7 +151,7 @@ ENTRY(xen_syscall32_target) + ENTRY(xen_sysenter_target) + lea 16(%rsp), %rsp /* strip %rcx, %r11 */ + mov $-ENOSYS, %rax +- pushq $VGCF_in_syscall ++ pushq $0 + jmp hypercall_iret + ENDPROC(xen_syscall32_target) + ENDPROC(xen_sysenter_target) +diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h +index 355fa6b..f9153a3 100644 +--- a/arch/x86/xen/xen-ops.h ++++ b/arch/x86/xen/xen-ops.h +@@ -25,6 +25,7 @@ extern struct shared_info *HYPERVISOR_shared_info; + + void xen_setup_mfn_list_list(void); + void xen_setup_shared_info(void); ++void xen_build_mfn_list_list(void); + void xen_setup_machphys_mapping(void); + pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn); + void xen_ident_map_ISA(void); +@@ -41,6 +42,7 @@ void __init xen_build_dynamic_phys_to_machine(void); + + void xen_init_irq_ops(void); + void xen_setup_timer(int cpu); ++void xen_setup_runstate_info(int cpu); + void xen_teardown_timer(int cpu); + cycle_t xen_clocksource_read(void); + void xen_setup_cpu_clockevents(void); +diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c +index d0a7df2..ec07c53 100644 +--- a/drivers/ata/pata_hpt37x.c ++++ b/drivers/ata/pata_hpt37x.c +@@ -24,7 +24,7 @@ + #include + + #define DRV_NAME "pata_hpt37x" +-#define DRV_VERSION "0.6.12" ++#define DRV_VERSION "0.6.14" + + struct hpt_clock { + u8 xfer_speed; +@@ -404,9 +404,8 @@ static void hpt370_set_piomode(struct ata_port *ap, struct ata_device *adev) + + pci_read_config_dword(pdev, addr1, ®); + mode = hpt37x_find_mode(ap, adev->pio_mode); +- mode &= ~0x8000000; /* No FIFO in PIO */ +- mode &= ~0x30070000; /* Leave config bits alone */ +- reg &= 0x30070000; /* Strip timing bits */ ++ mode &= 0xCFC3FFFF; /* Leave DMA bits alone */ ++ reg &= ~0xCFC3FFFF; /* Strip timing bits */ + pci_write_config_dword(pdev, addr1, reg | mode); + } + +@@ -423,8 +422,7 @@ static void hpt370_set_dmamode(struct ata_port *ap, struct ata_device *adev) + { + struct pci_dev *pdev = to_pci_dev(ap->host->dev); + u32 addr1, addr2; +- u32 reg; +- u32 mode; ++ u32 reg, mode, mask; + u8 fast; + + addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); +@@ -436,11 +434,12 @@ static void hpt370_set_dmamode(struct ata_port *ap, struct ata_device *adev) + fast |= 0x01; + pci_write_config_byte(pdev, addr2, fast); + ++ mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000; ++ + pci_read_config_dword(pdev, addr1, ®); + mode = hpt37x_find_mode(ap, adev->dma_mode); +- mode |= 0x8000000; /* FIFO in MWDMA or UDMA */ +- mode &= ~0xC0000000; /* Leave config bits alone */ +- reg &= 0xC0000000; /* Strip timing bits */ ++ mode &= mask; ++ reg &= ~mask; + pci_write_config_dword(pdev, addr1, reg | mode); + } + +@@ -508,9 +507,8 @@ static void hpt372_set_piomode(struct ata_port *ap, struct ata_device *adev) + mode = hpt37x_find_mode(ap, adev->pio_mode); + + printk("Find mode for %d reports %X\n", adev->pio_mode, mode); +- mode &= ~0x80000000; /* No FIFO in PIO */ +- mode &= ~0x30070000; /* Leave config bits alone */ +- reg &= 0x30070000; /* Strip timing bits */ ++ mode &= 0xCFC3FFFF; /* Leave DMA bits alone */ ++ reg &= ~0xCFC3FFFF; /* Strip timing bits */ + pci_write_config_dword(pdev, addr1, reg | mode); + } + +@@ -527,8 +525,7 @@ static void hpt372_set_dmamode(struct ata_port *ap, struct ata_device *adev) + { + struct pci_dev *pdev = to_pci_dev(ap->host->dev); + u32 addr1, addr2; +- u32 reg; +- u32 mode; ++ u32 reg, mode, mask; + u8 fast; + + addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); +@@ -539,12 +536,13 @@ static void hpt372_set_dmamode(struct ata_port *ap, struct ata_device *adev) + fast &= ~0x07; + pci_write_config_byte(pdev, addr2, fast); + ++ mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000; ++ + pci_read_config_dword(pdev, addr1, ®); + mode = hpt37x_find_mode(ap, adev->dma_mode); + printk("Find mode for DMA %d reports %X\n", adev->dma_mode, mode); +- mode &= ~0xC0000000; /* Leave config bits alone */ +- mode |= 0x80000000; /* FIFO in MWDMA or UDMA */ +- reg &= 0xC0000000; /* Strip timing bits */ ++ mode &= mask; ++ reg &= ~mask; + pci_write_config_dword(pdev, addr1, reg | mode); + } + +diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c +index 3d59fe0..21c5bd6 100644 +--- a/drivers/ata/pata_hpt3x2n.c ++++ b/drivers/ata/pata_hpt3x2n.c +@@ -25,7 +25,7 @@ + #include + + #define DRV_NAME "pata_hpt3x2n" +-#define DRV_VERSION "0.3.4" ++#define DRV_VERSION "0.3.7" + + enum { + HPT_PCI_FAST = (1 << 31), +@@ -185,9 +185,8 @@ static void hpt3x2n_set_piomode(struct ata_port *ap, struct ata_device *adev) + + pci_read_config_dword(pdev, addr1, ®); + mode = hpt3x2n_find_mode(ap, adev->pio_mode); +- mode &= ~0x8000000; /* No FIFO in PIO */ +- mode &= ~0x30070000; /* Leave config bits alone */ +- reg &= 0x30070000; /* Strip timing bits */ ++ mode &= 0xCFC3FFFF; /* Leave DMA bits alone */ ++ reg &= ~0xCFC3FFFF; /* Strip timing bits */ + pci_write_config_dword(pdev, addr1, reg | mode); + } + +@@ -204,8 +203,7 @@ static void hpt3x2n_set_dmamode(struct ata_port *ap, struct ata_device *adev) + { + struct pci_dev *pdev = to_pci_dev(ap->host->dev); + u32 addr1, addr2; +- u32 reg; +- u32 mode; ++ u32 reg, mode, mask; + u8 fast; + + addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); +@@ -216,11 +214,12 @@ static void hpt3x2n_set_dmamode(struct ata_port *ap, struct ata_device *adev) + fast &= ~0x07; + pci_write_config_byte(pdev, addr2, fast); + ++ mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000; ++ + pci_read_config_dword(pdev, addr1, ®); + mode = hpt3x2n_find_mode(ap, adev->dma_mode); +- mode |= 0x8000000; /* FIFO in MWDMA or UDMA */ +- mode &= ~0xC0000000; /* Leave config bits alone */ +- reg &= 0xC0000000; /* Strip timing bits */ ++ mode &= mask; ++ reg &= ~mask; + pci_write_config_dword(pdev, addr1, reg | mode); + } + +diff --git a/drivers/base/core.c b/drivers/base/core.c +index 6bee6af..1093179 100644 +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -56,7 +56,14 @@ static inline int device_is_not_partition(struct device *dev) + */ + const char *dev_driver_string(const struct device *dev) + { +- return dev->driver ? dev->driver->name : ++ struct device_driver *drv; ++ ++ /* dev->driver can change to NULL underneath us because of unbinding, ++ * so be careful about accessing it. dev->bus and dev->class should ++ * never change once they are set, so they don't need special care. ++ */ ++ drv = ACCESS_ONCE(dev->driver); ++ return drv ? drv->name : + (dev->bus ? dev->bus->name : + (dev->class ? dev->class->name : "")); + } +diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c +index 846d89e..0a4b75f 100644 +--- a/drivers/base/power/runtime.c ++++ b/drivers/base/power/runtime.c +@@ -777,7 +777,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status) + } + + if (parent) { +- spin_lock(&parent->power.lock); ++ spin_lock_nested(&parent->power.lock, SINGLE_DEPTH_NESTING); + + /* + * It is invalid to put an active child under a parent that is +diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c +index 94260aa..1e504de 100644 +--- a/drivers/firewire/ohci.c ++++ b/drivers/firewire/ohci.c +@@ -2209,6 +2209,13 @@ static int ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base, + page = payload >> PAGE_SHIFT; + offset = payload & ~PAGE_MASK; + rest = p->payload_length; ++ /* ++ * The controllers I've tested have not worked correctly when ++ * second_req_count is zero. Rather than do something we know won't ++ * work, return an error ++ */ ++ if (rest == 0) ++ return -EINVAL; + + /* FIXME: make packet-per-buffer/dual-buffer a context option */ + while (rest > 0) { +@@ -2262,7 +2269,7 @@ static int ohci_queue_iso_receive_packet_per_buffer(struct fw_iso_context *base, + unsigned long payload) + { + struct iso_context *ctx = container_of(base, struct iso_context, base); +- struct descriptor *d = NULL, *pd = NULL; ++ struct descriptor *d, *pd; + struct fw_iso_packet *p = packet; + dma_addr_t d_bus, page_bus; + u32 z, header_z, rest; +@@ -2300,8 +2307,9 @@ static int ohci_queue_iso_receive_packet_per_buffer(struct fw_iso_context *base, + d->data_address = cpu_to_le32(d_bus + (z * sizeof(*d))); + + rest = payload_per_buffer; ++ pd = d; + for (j = 1; j < z; j++) { +- pd = d + j; ++ pd++; + pd->control = cpu_to_le16(DESCRIPTOR_STATUS | + DESCRIPTOR_INPUT_MORE); + +diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c +index 0a6f0b3..332d743 100644 +--- a/drivers/gpu/drm/drm_irq.c ++++ b/drivers/gpu/drm/drm_irq.c +@@ -429,15 +429,21 @@ int drm_vblank_get(struct drm_device *dev, int crtc) + + spin_lock_irqsave(&dev->vbl_lock, irqflags); + /* Going from 0->1 means we have to enable interrupts again */ +- if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 && +- !dev->vblank_enabled[crtc]) { +- ret = dev->driver->enable_vblank(dev, crtc); +- DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret); +- if (ret) ++ if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) { ++ if (!dev->vblank_enabled[crtc]) { ++ ret = dev->driver->enable_vblank(dev, crtc); ++ DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret); ++ if (ret) ++ atomic_dec(&dev->vblank_refcount[crtc]); ++ else { ++ dev->vblank_enabled[crtc] = 1; ++ drm_update_vblank_count(dev, crtc); ++ } ++ } ++ } else { ++ if (!dev->vblank_enabled[crtc]) { + atomic_dec(&dev->vblank_refcount[crtc]); +- else { +- dev->vblank_enabled[crtc] = 1; +- drm_update_vblank_count(dev, crtc); ++ ret = -EINVAL; + } + } + spin_unlock_irqrestore(&dev->vbl_lock, irqflags); +@@ -464,6 +470,18 @@ void drm_vblank_put(struct drm_device *dev, int crtc) + } + EXPORT_SYMBOL(drm_vblank_put); + ++void drm_vblank_off(struct drm_device *dev, int crtc) ++{ ++ unsigned long irqflags; ++ ++ spin_lock_irqsave(&dev->vbl_lock, irqflags); ++ DRM_WAKEUP(&dev->vbl_queue[crtc]); ++ dev->vblank_enabled[crtc] = 0; ++ dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc); ++ spin_unlock_irqrestore(&dev->vbl_lock, irqflags); ++} ++EXPORT_SYMBOL(drm_vblank_off); ++ + /** + * drm_vblank_pre_modeset - account for vblanks across mode sets + * @dev: DRM device +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index a725f65..ecbafd0 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -957,6 +957,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); + #define IS_I85X(dev) ((dev)->pci_device == 0x3582) + #define IS_I855(dev) ((dev)->pci_device == 0x3582) + #define IS_I865G(dev) ((dev)->pci_device == 0x2572) ++#define IS_I8XX(dev) (IS_I830(dev) || IS_845G(dev) || IS_I85X(dev) || IS_I865G(dev)) + + #define IS_I915G(dev) ((dev)->pci_device == 0x2582 || (dev)->pci_device == 0x258a) + #define IS_I915GM(dev) ((dev)->pci_device == 0x2592) +@@ -1018,9 +1019,12 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); + */ + #define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \ + IS_I915GM(dev))) ++#define SUPPORTS_DIGITAL_OUTPUTS(dev) (IS_I9XX(dev) && !IS_IGD(dev)) + #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev)) + #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IGDNG(dev)) + #define SUPPORTS_EDP(dev) (IS_IGDNG_M(dev)) ++#define SUPPORTS_TV(dev) (IS_I9XX(dev) && IS_MOBILE(dev) && \ ++ !IS_IGDNG(dev) && !IS_IGD(dev)) + #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev) || IS_I965G(dev)) + /* dsparb controlled by hw only */ + #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev)) +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index abfc27b..5ddbd38 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -1288,6 +1288,7 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj) + list->hash.key = list->file_offset_node->start; + if (drm_ht_insert_item(&mm->offset_hash, &list->hash)) { + DRM_ERROR("failed to add to map hash\n"); ++ ret = -ENOMEM; + goto out_free_mm; + } + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 099f420..f1de53b 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -1482,6 +1482,15 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) + case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_SUSPEND: + DRM_DEBUG("crtc %d dpms on\n", pipe); ++ ++ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { ++ temp = I915_READ(PCH_LVDS); ++ if ((temp & LVDS_PORT_EN) == 0) { ++ I915_WRITE(PCH_LVDS, temp | LVDS_PORT_EN); ++ POSTING_READ(PCH_LVDS); ++ } ++ } ++ + if (HAS_eDP) { + /* enable eDP PLL */ + igdng_enable_pll_edp(crtc); +@@ -1666,8 +1675,6 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) + case DRM_MODE_DPMS_OFF: + DRM_DEBUG("crtc %d dpms off\n", pipe); + +- i915_disable_vga(dev); +- + /* Disable display plane */ + temp = I915_READ(dspcntr_reg); + if ((temp & DISPLAY_PLANE_ENABLE) != 0) { +@@ -1677,6 +1684,8 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) + I915_READ(dspbase_reg); + } + ++ i915_disable_vga(dev); ++ + /* disable cpu pipe, disable after all planes disabled */ + temp = I915_READ(pipeconf_reg); + if ((temp & PIPEACONF_ENABLE) != 0) { +@@ -1697,9 +1706,15 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) + } else + DRM_DEBUG("crtc %d is disabled\n", pipe); + +- if (HAS_eDP) { +- igdng_disable_pll_edp(crtc); ++ udelay(100); ++ ++ /* Disable PF */ ++ temp = I915_READ(pf_ctl_reg); ++ if ((temp & PF_ENABLE) != 0) { ++ I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); ++ I915_READ(pf_ctl_reg); + } ++ I915_WRITE(pf_win_size, 0); + + /* disable CPU FDI tx and PCH FDI rx */ + temp = I915_READ(fdi_tx_reg); +@@ -1725,6 +1740,13 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) + + udelay(100); + ++ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { ++ temp = I915_READ(PCH_LVDS); ++ I915_WRITE(PCH_LVDS, temp & ~LVDS_PORT_EN); ++ I915_READ(PCH_LVDS); ++ udelay(100); ++ } ++ + /* disable PCH transcoder */ + temp = I915_READ(transconf_reg); + if ((temp & TRANS_ENABLE) != 0) { +@@ -1744,6 +1766,8 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) + } + } + ++ udelay(100); ++ + /* disable PCH DPLL */ + temp = I915_READ(pch_dpll_reg); + if ((temp & DPLL_VCO_ENABLE) != 0) { +@@ -1751,14 +1775,20 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) + I915_READ(pch_dpll_reg); + } + +- temp = I915_READ(fdi_rx_reg); +- if ((temp & FDI_RX_PLL_ENABLE) != 0) { +- temp &= ~FDI_SEL_PCDCLK; +- temp &= ~FDI_RX_PLL_ENABLE; +- I915_WRITE(fdi_rx_reg, temp); +- I915_READ(fdi_rx_reg); ++ if (HAS_eDP) { ++ igdng_disable_pll_edp(crtc); + } + ++ temp = I915_READ(fdi_rx_reg); ++ temp &= ~FDI_SEL_PCDCLK; ++ I915_WRITE(fdi_rx_reg, temp); ++ I915_READ(fdi_rx_reg); ++ ++ temp = I915_READ(fdi_rx_reg); ++ temp &= ~FDI_RX_PLL_ENABLE; ++ I915_WRITE(fdi_rx_reg, temp); ++ I915_READ(fdi_rx_reg); ++ + /* Disable CPU FDI TX PLL */ + temp = I915_READ(fdi_tx_reg); + if ((temp & FDI_TX_PLL_ENABLE) != 0) { +@@ -1767,16 +1797,8 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) + udelay(100); + } + +- /* Disable PF */ +- temp = I915_READ(pf_ctl_reg); +- if ((temp & PF_ENABLE) != 0) { +- I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); +- I915_READ(pf_ctl_reg); +- } +- I915_WRITE(pf_win_size, 0); +- + /* Wait for the clocks to turn off. */ +- udelay(150); ++ udelay(100); + break; + } + } +@@ -1845,6 +1867,7 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) + intel_update_watermarks(dev); + /* Give the overlay scaler a chance to disable if it's on this pipe */ + //intel_crtc_dpms_video(crtc, FALSE); TODO ++ drm_vblank_off(dev, pipe); + + if (dev_priv->cfb_plane == plane && + dev_priv->display.disable_fbc) +@@ -4118,7 +4141,7 @@ static void intel_setup_outputs(struct drm_device *dev) + if (I915_READ(PCH_DP_D) & DP_DETECTED) + intel_dp_init(dev, PCH_DP_D); + +- } else if (IS_I9XX(dev)) { ++ } else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) { + bool found = false; + + if (I915_READ(SDVOB) & SDVO_DETECTED) { +@@ -4145,10 +4168,10 @@ static void intel_setup_outputs(struct drm_device *dev) + + if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED)) + intel_dp_init(dev, DP_D); +- } else ++ } else if (IS_I8XX(dev)) + intel_dvo_init(dev); + +- if (IS_I9XX(dev) && IS_MOBILE(dev) && !IS_IGDNG(dev)) ++ if (SUPPORTS_TV(dev)) + intel_tv_init(dev); + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index d834475..92a3d7b 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -1254,11 +1254,11 @@ intel_dp_init(struct drm_device *dev, int output_reg) + else + intel_output->type = INTEL_OUTPUT_DISPLAYPORT; + +- if (output_reg == DP_B) ++ if (output_reg == DP_B || output_reg == PCH_DP_B) + intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT); +- else if (output_reg == DP_C) ++ else if (output_reg == DP_C || output_reg == PCH_DP_C) + intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT); +- else if (output_reg == DP_D) ++ else if (output_reg == DP_D || output_reg == PCH_DP_D) + intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); + + if (IS_eDP(intel_output)) { +diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c +index 9ca9179..5b28b4e 100644 +--- a/drivers/gpu/drm/i915/intel_tv.c ++++ b/drivers/gpu/drm/i915/intel_tv.c +@@ -1213,20 +1213,17 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, + tv_ctl |= TV_TRILEVEL_SYNC; + if (tv_mode->pal_burst) + tv_ctl |= TV_PAL_BURST; ++ + scctl1 = 0; +- /* dda1 implies valid video levels */ +- if (tv_mode->dda1_inc) { ++ if (tv_mode->dda1_inc) + scctl1 |= TV_SC_DDA1_EN; +- } +- + if (tv_mode->dda2_inc) + scctl1 |= TV_SC_DDA2_EN; +- + if (tv_mode->dda3_inc) + scctl1 |= TV_SC_DDA3_EN; +- + scctl1 |= tv_mode->sc_reset; +- scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT; ++ if (video_levels) ++ scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT; + scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT; + + scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT | +diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c +index c15287a..c6777cb 100644 +--- a/drivers/gpu/drm/radeon/atombios_crtc.c ++++ b/drivers/gpu/drm/radeon/atombios_crtc.c +@@ -241,6 +241,7 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) + { + struct drm_device *dev = crtc->dev; + struct radeon_device *rdev = dev->dev_private; ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); + + switch (mode) { + case DRM_MODE_DPMS_ON: +@@ -248,20 +249,19 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) + if (ASIC_IS_DCE3(rdev)) + atombios_enable_crtc_memreq(crtc, 1); + atombios_blank_crtc(crtc, 0); ++ drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); ++ radeon_crtc_load_lut(crtc); + break; + case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_SUSPEND: + case DRM_MODE_DPMS_OFF: ++ drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); + atombios_blank_crtc(crtc, 1); + if (ASIC_IS_DCE3(rdev)) + atombios_enable_crtc_memreq(crtc, 0); + atombios_enable_crtc(crtc, 0); + break; + } +- +- if (mode != DRM_MODE_DPMS_OFF) { +- radeon_crtc_load_lut(crtc); +- } + } + + static void +diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c +index 2ed88a8..969502a 100644 +--- a/drivers/gpu/drm/radeon/radeon_atombios.c ++++ b/drivers/gpu/drm/radeon/radeon_atombios.c +@@ -135,6 +135,14 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, + } + } + ++ /* HIS X1300 is DVI+VGA, not DVI+DVI */ ++ if ((dev->pdev->device == 0x7146) && ++ (dev->pdev->subsystem_vendor == 0x17af) && ++ (dev->pdev->subsystem_device == 0x2058)) { ++ if (supported_device == ATOM_DEVICE_DFP1_SUPPORT) ++ return false; ++ } ++ + /* Funky macbooks */ + if ((dev->pdev->device == 0x71C5) && + (dev->pdev->subsystem_vendor == 0x106b) && +diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +index 8d0b7aa..22ce4d6 100644 +--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c ++++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +@@ -292,8 +292,7 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) + uint32_t mask; + + if (radeon_crtc->crtc_id) +- mask = (RADEON_CRTC2_EN | +- RADEON_CRTC2_DISP_DIS | ++ mask = (RADEON_CRTC2_DISP_DIS | + RADEON_CRTC2_VSYNC_DIS | + RADEON_CRTC2_HSYNC_DIS | + RADEON_CRTC2_DISP_REQ_EN_B); +@@ -305,7 +304,7 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) + switch (mode) { + case DRM_MODE_DPMS_ON: + if (radeon_crtc->crtc_id) +- WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~mask); ++ WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~(RADEON_CRTC2_EN | mask)); + else { + WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN | + RADEON_CRTC_DISP_REQ_EN_B)); +@@ -319,7 +318,7 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) + case DRM_MODE_DPMS_OFF: + drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); + if (radeon_crtc->crtc_id) +- WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~mask); ++ WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~(RADEON_CRTC2_EN | mask)); + else { + WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN | + RADEON_CRTC_DISP_REQ_EN_B)); +diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c +index 5f117cd..4444f48 100644 +--- a/drivers/gpu/drm/radeon/rs600.c ++++ b/drivers/gpu/drm/radeon/rs600.c +@@ -301,9 +301,7 @@ int rs600_mc_wait_for_idle(struct radeon_device *rdev) + + void rs600_gpu_init(struct radeon_device *rdev) + { +- /* FIXME: HDP same place on rs600 ? */ + r100_hdp_reset(rdev); +- /* FIXME: is this correct ? */ + r420_pipes_init(rdev); + /* Wait for mc idle */ + if (rs600_mc_wait_for_idle(rdev)) +@@ -312,9 +310,20 @@ void rs600_gpu_init(struct radeon_device *rdev) + + void rs600_vram_info(struct radeon_device *rdev) + { +- /* FIXME: to do or is these values sane ? */ + rdev->mc.vram_is_ddr = true; + rdev->mc.vram_width = 128; ++ ++ rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); ++ rdev->mc.mc_vram_size = rdev->mc.real_vram_size; ++ ++ rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); ++ rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); ++ ++ if (rdev->mc.mc_vram_size > rdev->mc.aper_size) ++ rdev->mc.mc_vram_size = rdev->mc.aper_size; ++ ++ if (rdev->mc.real_vram_size > rdev->mc.aper_size) ++ rdev->mc.real_vram_size = rdev->mc.aper_size; + } + + void rs600_bandwidth_update(struct radeon_device *rdev) +diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c +index 2754717..b12ff76 100644 +--- a/drivers/gpu/drm/radeon/rs690.c ++++ b/drivers/gpu/drm/radeon/rs690.c +@@ -131,24 +131,25 @@ void rs690_pm_info(struct radeon_device *rdev) + + void rs690_vram_info(struct radeon_device *rdev) + { +- uint32_t tmp; + fixed20_12 a; + + rs400_gart_adjust_size(rdev); +- /* DDR for all card after R300 & IGP */ ++ + rdev->mc.vram_is_ddr = true; +- /* FIXME: is this correct for RS690/RS740 ? */ +- tmp = RREG32(RADEON_MEM_CNTL); +- if (tmp & R300_MEM_NUM_CHANNELS_MASK) { +- rdev->mc.vram_width = 128; +- } else { +- rdev->mc.vram_width = 64; +- } ++ rdev->mc.vram_width = 128; ++ + rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); + rdev->mc.mc_vram_size = rdev->mc.real_vram_size; + + rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); + rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); ++ ++ if (rdev->mc.mc_vram_size > rdev->mc.aper_size) ++ rdev->mc.mc_vram_size = rdev->mc.aper_size; ++ ++ if (rdev->mc.real_vram_size > rdev->mc.aper_size) ++ rdev->mc.real_vram_size = rdev->mc.aper_size; ++ + rs690_pm_info(rdev); + /* FIXME: we should enforce default clock in case GPU is not in + * default setup +diff --git a/drivers/ide/slc90e66.c b/drivers/ide/slc90e66.c +index 9aec78d..1ccfb40 100644 +--- a/drivers/ide/slc90e66.c ++++ b/drivers/ide/slc90e66.c +@@ -91,8 +91,7 @@ static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed) + + if (!(reg48 & u_flag)) + pci_write_config_word(dev, 0x48, reg48|u_flag); +- /* FIXME: (reg4a & a_speed) ? */ +- if ((reg4a & u_speed) != u_speed) { ++ if ((reg4a & a_speed) != u_speed) { + pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); + pci_read_config_word(dev, 0x4a, ®4a); + pci_write_config_word(dev, 0x4a, reg4a|u_speed); +diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c +index 556f0fe..386a797 100644 +--- a/drivers/macintosh/therm_adt746x.c ++++ b/drivers/macintosh/therm_adt746x.c +@@ -79,6 +79,7 @@ struct thermostat { + u8 limits[3]; + int last_speed[2]; + int last_var[2]; ++ int pwm_inv[2]; + }; + + static enum {ADT7460, ADT7467} therm_type; +@@ -229,19 +230,23 @@ static void write_fan_speed(struct thermostat *th, int speed, int fan) + + if (speed >= 0) { + manual = read_reg(th, MANUAL_MODE[fan]); ++ manual &= ~INVERT_MASK; + write_reg(th, MANUAL_MODE[fan], +- (manual|MANUAL_MASK) & (~INVERT_MASK)); ++ manual | MANUAL_MASK | th->pwm_inv[fan]); + write_reg(th, FAN_SPD_SET[fan], speed); + } else { + /* back to automatic */ + if(therm_type == ADT7460) { + manual = read_reg(th, + MANUAL_MODE[fan]) & (~MANUAL_MASK); +- ++ manual &= ~INVERT_MASK; ++ manual |= th->pwm_inv[fan]; + write_reg(th, + MANUAL_MODE[fan], manual|REM_CONTROL[fan]); + } else { + manual = read_reg(th, MANUAL_MODE[fan]); ++ manual &= ~INVERT_MASK; ++ manual |= th->pwm_inv[fan]; + write_reg(th, MANUAL_MODE[fan], manual&(~AUTO_MASK)); + } + } +@@ -418,6 +423,10 @@ static int probe_thermostat(struct i2c_client *client, + + thermostat = th; + ++ /* record invert bit status because fw can corrupt it after suspend */ ++ th->pwm_inv[0] = read_reg(th, MANUAL_MODE[0]) & INVERT_MASK; ++ th->pwm_inv[1] = read_reg(th, MANUAL_MODE[1]) & INVERT_MASK; ++ + /* be sure to really write fan speed the first time */ + th->last_speed[0] = -2; + th->last_speed[1] = -2; +diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c +index 961fa0e..6c68b9e 100644 +--- a/drivers/macintosh/windfarm_smu_controls.c ++++ b/drivers/macintosh/windfarm_smu_controls.c +@@ -202,6 +202,8 @@ static struct smu_fan_control *smu_fan_create(struct device_node *node, + fct->ctrl.name = "cpu-front-fan-1"; + else if (!strcmp(l, "CPU A PUMP")) + fct->ctrl.name = "cpu-pump-0"; ++ else if (!strcmp(l, "CPU B PUMP")) ++ fct->ctrl.name = "cpu-pump-1"; + else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan") || + !strcmp(l, "EXPANSION SLOTS INTAKE")) + fct->ctrl.name = "slots-fan"; +diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c +index 60e2b32..a5e5f2f 100644 +--- a/drivers/md/bitmap.c ++++ b/drivers/md/bitmap.c +@@ -1078,23 +1078,31 @@ static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap, + * out to disk + */ + +-void bitmap_daemon_work(struct bitmap *bitmap) ++void bitmap_daemon_work(mddev_t *mddev) + { ++ struct bitmap *bitmap; + unsigned long j; + unsigned long flags; + struct page *page = NULL, *lastpage = NULL; + int blocks; + void *paddr; + +- if (bitmap == NULL) ++ /* Use a mutex to guard daemon_work against ++ * bitmap_destroy. ++ */ ++ mutex_lock(&mddev->bitmap_mutex); ++ bitmap = mddev->bitmap; ++ if (bitmap == NULL) { ++ mutex_unlock(&mddev->bitmap_mutex); + return; ++ } + if (time_before(jiffies, bitmap->daemon_lastrun + bitmap->daemon_sleep*HZ)) + goto done; + + bitmap->daemon_lastrun = jiffies; + if (bitmap->allclean) { + bitmap->mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT; +- return; ++ goto done; + } + bitmap->allclean = 1; + +@@ -1203,6 +1211,7 @@ void bitmap_daemon_work(struct bitmap *bitmap) + done: + if (bitmap->allclean == 0) + bitmap->mddev->thread->timeout = bitmap->daemon_sleep * HZ; ++ mutex_unlock(&mddev->bitmap_mutex); + } + + static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap, +@@ -1541,9 +1550,9 @@ void bitmap_flush(mddev_t *mddev) + */ + sleep = bitmap->daemon_sleep; + bitmap->daemon_sleep = 0; +- bitmap_daemon_work(bitmap); +- bitmap_daemon_work(bitmap); +- bitmap_daemon_work(bitmap); ++ bitmap_daemon_work(mddev); ++ bitmap_daemon_work(mddev); ++ bitmap_daemon_work(mddev); + bitmap->daemon_sleep = sleep; + bitmap_update_sb(bitmap); + } +@@ -1574,6 +1583,7 @@ static void bitmap_free(struct bitmap *bitmap) + kfree(bp); + kfree(bitmap); + } ++ + void bitmap_destroy(mddev_t *mddev) + { + struct bitmap *bitmap = mddev->bitmap; +@@ -1581,7 +1591,9 @@ void bitmap_destroy(mddev_t *mddev) + if (!bitmap) /* there was no bitmap */ + return; + ++ mutex_lock(&mddev->bitmap_mutex); + mddev->bitmap = NULL; /* disconnect from the md device */ ++ mutex_unlock(&mddev->bitmap_mutex); + if (mddev->thread) + mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT; + +diff --git a/drivers/md/bitmap.h b/drivers/md/bitmap.h +index e989006..7e38d13 100644 +--- a/drivers/md/bitmap.h ++++ b/drivers/md/bitmap.h +@@ -282,7 +282,7 @@ void bitmap_close_sync(struct bitmap *bitmap); + void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector); + + void bitmap_unplug(struct bitmap *bitmap); +-void bitmap_daemon_work(struct bitmap *bitmap); ++void bitmap_daemon_work(mddev_t *mddev); + #endif + + #endif +diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c +index ed10381..959d6d1 100644 +--- a/drivers/md/dm-crypt.c ++++ b/drivers/md/dm-crypt.c +@@ -1,7 +1,7 @@ + /* + * Copyright (C) 2003 Christophe Saout + * Copyright (C) 2004 Clemens Fruhwirth +- * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved. ++ * Copyright (C) 2006-2009 Red Hat, Inc. All rights reserved. + * + * This file is released under the GPL. + */ +@@ -71,10 +71,21 @@ struct crypt_iv_operations { + int (*ctr)(struct crypt_config *cc, struct dm_target *ti, + const char *opts); + void (*dtr)(struct crypt_config *cc); +- const char *(*status)(struct crypt_config *cc); ++ int (*init)(struct crypt_config *cc); ++ int (*wipe)(struct crypt_config *cc); + int (*generator)(struct crypt_config *cc, u8 *iv, sector_t sector); + }; + ++struct iv_essiv_private { ++ struct crypto_cipher *tfm; ++ struct crypto_hash *hash_tfm; ++ u8 *salt; ++}; ++ ++struct iv_benbi_private { ++ int shift; ++}; ++ + /* + * Crypt: maps a linear range of a block device + * and encrypts / decrypts at the same time. +@@ -102,8 +113,8 @@ struct crypt_config { + struct crypt_iv_operations *iv_gen_ops; + char *iv_mode; + union { +- struct crypto_cipher *essiv_tfm; +- int benbi_shift; ++ struct iv_essiv_private essiv; ++ struct iv_benbi_private benbi; + } iv_gen_private; + sector_t iv_offset; + unsigned int iv_size; +@@ -169,88 +180,114 @@ static int crypt_iv_plain_gen(struct crypt_config *cc, u8 *iv, sector_t sector) + return 0; + } + +-static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti, +- const char *opts) ++/* Initialise ESSIV - compute salt but no local memory allocations */ ++static int crypt_iv_essiv_init(struct crypt_config *cc) + { +- struct crypto_cipher *essiv_tfm; +- struct crypto_hash *hash_tfm; ++ struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv; + struct hash_desc desc; + struct scatterlist sg; +- unsigned int saltsize; +- u8 *salt; + int err; + +- if (opts == NULL) { ++ sg_init_one(&sg, cc->key, cc->key_size); ++ desc.tfm = essiv->hash_tfm; ++ desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; ++ ++ err = crypto_hash_digest(&desc, &sg, cc->key_size, essiv->salt); ++ if (err) ++ return err; ++ ++ return crypto_cipher_setkey(essiv->tfm, essiv->salt, ++ crypto_hash_digestsize(essiv->hash_tfm)); ++} ++ ++/* Wipe salt and reset key derived from volume key */ ++static int crypt_iv_essiv_wipe(struct crypt_config *cc) ++{ ++ struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv; ++ unsigned salt_size = crypto_hash_digestsize(essiv->hash_tfm); ++ ++ memset(essiv->salt, 0, salt_size); ++ ++ return crypto_cipher_setkey(essiv->tfm, essiv->salt, salt_size); ++} ++ ++static void crypt_iv_essiv_dtr(struct crypt_config *cc) ++{ ++ struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv; ++ ++ crypto_free_cipher(essiv->tfm); ++ essiv->tfm = NULL; ++ ++ crypto_free_hash(essiv->hash_tfm); ++ essiv->hash_tfm = NULL; ++ ++ kzfree(essiv->salt); ++ essiv->salt = NULL; ++} ++ ++static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti, ++ const char *opts) ++{ ++ struct crypto_cipher *essiv_tfm = NULL; ++ struct crypto_hash *hash_tfm = NULL; ++ u8 *salt = NULL; ++ int err; ++ ++ if (!opts) { + ti->error = "Digest algorithm missing for ESSIV mode"; + return -EINVAL; + } + +- /* Hash the cipher key with the given hash algorithm */ ++ /* Allocate hash algorithm */ + hash_tfm = crypto_alloc_hash(opts, 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(hash_tfm)) { + ti->error = "Error initializing ESSIV hash"; +- return PTR_ERR(hash_tfm); ++ err = PTR_ERR(hash_tfm); ++ goto bad; + } + +- saltsize = crypto_hash_digestsize(hash_tfm); +- salt = kmalloc(saltsize, GFP_KERNEL); +- if (salt == NULL) { ++ salt = kzalloc(crypto_hash_digestsize(hash_tfm), GFP_KERNEL); ++ if (!salt) { + ti->error = "Error kmallocing salt storage in ESSIV"; +- crypto_free_hash(hash_tfm); +- return -ENOMEM; ++ err = -ENOMEM; ++ goto bad; + } + +- sg_init_one(&sg, cc->key, cc->key_size); +- desc.tfm = hash_tfm; +- desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; +- err = crypto_hash_digest(&desc, &sg, cc->key_size, salt); +- crypto_free_hash(hash_tfm); +- +- if (err) { +- ti->error = "Error calculating hash in ESSIV"; +- kfree(salt); +- return err; +- } +- +- /* Setup the essiv_tfm with the given salt */ ++ /* Allocate essiv_tfm */ + essiv_tfm = crypto_alloc_cipher(cc->cipher, 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(essiv_tfm)) { + ti->error = "Error allocating crypto tfm for ESSIV"; +- kfree(salt); +- return PTR_ERR(essiv_tfm); ++ err = PTR_ERR(essiv_tfm); ++ goto bad; + } + if (crypto_cipher_blocksize(essiv_tfm) != + crypto_ablkcipher_ivsize(cc->tfm)) { + ti->error = "Block size of ESSIV cipher does " + "not match IV size of block cipher"; +- crypto_free_cipher(essiv_tfm); +- kfree(salt); +- return -EINVAL; +- } +- err = crypto_cipher_setkey(essiv_tfm, salt, saltsize); +- if (err) { +- ti->error = "Failed to set key for ESSIV cipher"; +- crypto_free_cipher(essiv_tfm); +- kfree(salt); +- return err; ++ err = -EINVAL; ++ goto bad; + } +- kfree(salt); + +- cc->iv_gen_private.essiv_tfm = essiv_tfm; ++ cc->iv_gen_private.essiv.salt = salt; ++ cc->iv_gen_private.essiv.tfm = essiv_tfm; ++ cc->iv_gen_private.essiv.hash_tfm = hash_tfm; ++ + return 0; +-} + +-static void crypt_iv_essiv_dtr(struct crypt_config *cc) +-{ +- crypto_free_cipher(cc->iv_gen_private.essiv_tfm); +- cc->iv_gen_private.essiv_tfm = NULL; ++bad: ++ if (essiv_tfm && !IS_ERR(essiv_tfm)) ++ crypto_free_cipher(essiv_tfm); ++ if (hash_tfm && !IS_ERR(hash_tfm)) ++ crypto_free_hash(hash_tfm); ++ kfree(salt); ++ return err; + } + + static int crypt_iv_essiv_gen(struct crypt_config *cc, u8 *iv, sector_t sector) + { + memset(iv, 0, cc->iv_size); + *(u64 *)iv = cpu_to_le64(sector); +- crypto_cipher_encrypt_one(cc->iv_gen_private.essiv_tfm, iv, iv); ++ crypto_cipher_encrypt_one(cc->iv_gen_private.essiv.tfm, iv, iv); + return 0; + } + +@@ -273,7 +310,7 @@ static int crypt_iv_benbi_ctr(struct crypt_config *cc, struct dm_target *ti, + return -EINVAL; + } + +- cc->iv_gen_private.benbi_shift = 9 - log; ++ cc->iv_gen_private.benbi.shift = 9 - log; + + return 0; + } +@@ -288,7 +325,7 @@ static int crypt_iv_benbi_gen(struct crypt_config *cc, u8 *iv, sector_t sector) + + memset(iv, 0, cc->iv_size - sizeof(u64)); /* rest is cleared below */ + +- val = cpu_to_be64(((u64)sector << cc->iv_gen_private.benbi_shift) + 1); ++ val = cpu_to_be64(((u64)sector << cc->iv_gen_private.benbi.shift) + 1); + put_unaligned(val, (__be64 *)(iv + cc->iv_size - sizeof(u64))); + + return 0; +@@ -308,6 +345,8 @@ static struct crypt_iv_operations crypt_iv_plain_ops = { + static struct crypt_iv_operations crypt_iv_essiv_ops = { + .ctr = crypt_iv_essiv_ctr, + .dtr = crypt_iv_essiv_dtr, ++ .init = crypt_iv_essiv_init, ++ .wipe = crypt_iv_essiv_wipe, + .generator = crypt_iv_essiv_gen + }; + +@@ -1039,6 +1078,12 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) + cc->iv_gen_ops->ctr(cc, ti, ivopts) < 0) + goto bad_ivmode; + ++ if (cc->iv_gen_ops && cc->iv_gen_ops->init && ++ cc->iv_gen_ops->init(cc) < 0) { ++ ti->error = "Error initialising IV"; ++ goto bad_slab_pool; ++ } ++ + cc->iv_size = crypto_ablkcipher_ivsize(tfm); + if (cc->iv_size) + /* at least a 64 bit sector number should fit in our buffer */ +@@ -1278,6 +1323,7 @@ static void crypt_resume(struct dm_target *ti) + static int crypt_message(struct dm_target *ti, unsigned argc, char **argv) + { + struct crypt_config *cc = ti->private; ++ int ret = -EINVAL; + + if (argc < 2) + goto error; +@@ -1287,10 +1333,22 @@ static int crypt_message(struct dm_target *ti, unsigned argc, char **argv) + DMWARN("not suspended during key manipulation."); + return -EINVAL; + } +- if (argc == 3 && !strnicmp(argv[1], MESG_STR("set"))) +- return crypt_set_key(cc, argv[2]); +- if (argc == 2 && !strnicmp(argv[1], MESG_STR("wipe"))) ++ if (argc == 3 && !strnicmp(argv[1], MESG_STR("set"))) { ++ ret = crypt_set_key(cc, argv[2]); ++ if (ret) ++ return ret; ++ if (cc->iv_gen_ops && cc->iv_gen_ops->init) ++ ret = cc->iv_gen_ops->init(cc); ++ return ret; ++ } ++ if (argc == 2 && !strnicmp(argv[1], MESG_STR("wipe"))) { ++ if (cc->iv_gen_ops && cc->iv_gen_ops->wipe) { ++ ret = cc->iv_gen_ops->wipe(cc); ++ if (ret) ++ return ret; ++ } + return crypt_wipe_key(cc); ++ } + } + + error: +diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c +index 7dbe652..2052159 100644 +--- a/drivers/md/dm-exception-store.c ++++ b/drivers/md/dm-exception-store.c +@@ -216,7 +216,8 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, + type = get_type("N"); + else { + ti->error = "Persistent flag is not P or N"; +- return -EINVAL; ++ r = -EINVAL; ++ goto bad_type; + } + + if (!type) { +diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c +index a679429..d19854c 100644 +--- a/drivers/md/dm-ioctl.c ++++ b/drivers/md/dm-ioctl.c +@@ -56,6 +56,11 @@ static void dm_hash_remove_all(int keep_open_devices); + */ + static DECLARE_RWSEM(_hash_lock); + ++/* ++ * Protects use of mdptr to obtain hash cell name and uuid from mapped device. ++ */ ++static DEFINE_MUTEX(dm_hash_cells_mutex); ++ + static void init_buckets(struct list_head *buckets) + { + unsigned int i; +@@ -206,7 +211,9 @@ static int dm_hash_insert(const char *name, const char *uuid, struct mapped_devi + list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid)); + } + dm_get(md); ++ mutex_lock(&dm_hash_cells_mutex); + dm_set_mdptr(md, cell); ++ mutex_unlock(&dm_hash_cells_mutex); + up_write(&_hash_lock); + + return 0; +@@ -224,7 +231,9 @@ static void __hash_remove(struct hash_cell *hc) + /* remove from the dev hash */ + list_del(&hc->uuid_list); + list_del(&hc->name_list); ++ mutex_lock(&dm_hash_cells_mutex); + dm_set_mdptr(hc->md, NULL); ++ mutex_unlock(&dm_hash_cells_mutex); + + table = dm_get_table(hc->md); + if (table) { +@@ -321,7 +330,9 @@ static int dm_hash_rename(uint32_t cookie, const char *old, const char *new) + */ + list_del(&hc->name_list); + old_name = hc->name; ++ mutex_lock(&dm_hash_cells_mutex); + hc->name = new_name; ++ mutex_unlock(&dm_hash_cells_mutex); + list_add(&hc->name_list, _name_buckets + hash_str(new_name)); + + /* +@@ -1582,8 +1593,7 @@ int dm_copy_name_and_uuid(struct mapped_device *md, char *name, char *uuid) + if (!md) + return -ENXIO; + +- dm_get(md); +- down_read(&_hash_lock); ++ mutex_lock(&dm_hash_cells_mutex); + hc = dm_get_mdptr(md); + if (!hc || hc->md != md) { + r = -ENXIO; +@@ -1596,8 +1606,7 @@ int dm_copy_name_and_uuid(struct mapped_device *md, char *name, char *uuid) + strcpy(uuid, hc->uuid ? : ""); + + out: +- up_read(&_hash_lock); +- dm_put(md); ++ mutex_unlock(&dm_hash_cells_mutex); + + return r; + } +diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c +index 3a3ba46..8a4a9c8 100644 +--- a/drivers/md/dm-snap.c ++++ b/drivers/md/dm-snap.c +@@ -553,6 +553,8 @@ static int init_hash_tables(struct dm_snapshot *s) + hash_size = min(origin_dev_size, cow_dev_size) >> s->store->chunk_shift; + hash_size = min(hash_size, max_buckets); + ++ if (hash_size < 64) ++ hash_size = 64; + hash_size = rounddown_pow_of_two(hash_size); + if (init_exception_table(&s->complete, hash_size, + DM_CHUNK_CONSECUTIVE_BITS)) +@@ -1152,10 +1154,11 @@ static int snapshot_status(struct dm_target *ti, status_type_t type, + unsigned sz = 0; + struct dm_snapshot *snap = ti->private; + +- down_write(&snap->lock); +- + switch (type) { + case STATUSTYPE_INFO: ++ ++ down_write(&snap->lock); ++ + if (!snap->valid) + DMEMIT("Invalid"); + else { +@@ -1171,6 +1174,9 @@ static int snapshot_status(struct dm_target *ti, status_type_t type, + else + DMEMIT("Unknown"); + } ++ ++ up_write(&snap->lock); ++ + break; + + case STATUSTYPE_TABLE: +@@ -1185,8 +1191,6 @@ static int snapshot_status(struct dm_target *ti, status_type_t type, + break; + } + +- up_write(&snap->lock); +- + return 0; + } + +diff --git a/drivers/md/dm-uevent.c b/drivers/md/dm-uevent.c +index 6f65883..c7c555a 100644 +--- a/drivers/md/dm-uevent.c ++++ b/drivers/md/dm-uevent.c +@@ -139,14 +139,13 @@ void dm_send_uevents(struct list_head *events, struct kobject *kobj) + list_del_init(&event->elist); + + /* +- * Need to call dm_copy_name_and_uuid from here for now. +- * Context of previous var adds and locking used for +- * hash_cell not compatable. ++ * When a device is being removed this copy fails and we ++ * discard these unsent events. + */ + if (dm_copy_name_and_uuid(event->md, event->name, + event->uuid)) { +- DMERR("%s: dm_copy_name_and_uuid() failed", +- __func__); ++ DMINFO("%s: skipping sending uevent for lost device", ++ __func__); + goto uevent_free; + } + +diff --git a/drivers/md/md.c b/drivers/md/md.c +index b182f86..02e4551 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -367,6 +367,7 @@ static mddev_t * mddev_find(dev_t unit) + + mutex_init(&new->open_mutex); + mutex_init(&new->reconfig_mutex); ++ mutex_init(&new->bitmap_mutex); + INIT_LIST_HEAD(&new->disks); + INIT_LIST_HEAD(&new->all_mddevs); + init_timer(&new->safemode_timer); +@@ -6629,7 +6630,7 @@ void md_check_recovery(mddev_t *mddev) + + + if (mddev->bitmap) +- bitmap_daemon_work(mddev->bitmap); ++ bitmap_daemon_work(mddev); + + if (mddev->ro) + return; +diff --git a/drivers/md/md.h b/drivers/md/md.h +index f184b69..87430fe 100644 +--- a/drivers/md/md.h ++++ b/drivers/md/md.h +@@ -289,6 +289,7 @@ struct mddev_s + * hot-adding a bitmap. It should + * eventually be settable by sysfs. + */ ++ struct mutex bitmap_mutex; + + struct list_head all_mddevs; + }; +diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c +index 2d02698..7eb1bf7 100644 +--- a/drivers/media/common/tuners/mxl5007t.c ++++ b/drivers/media/common/tuners/mxl5007t.c +@@ -196,7 +196,7 @@ static void copy_reg_bits(struct reg_pair_t *reg_pair1, + i = j = 0; + + while (reg_pair1[i].reg || reg_pair1[i].val) { +- while (reg_pair2[j].reg || reg_pair2[j].reg) { ++ while (reg_pair2[j].reg || reg_pair2[j].val) { + if (reg_pair1[i].reg != reg_pair2[j].reg) { + j++; + continue; +diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c +index a5c190e..e165578 100644 +--- a/drivers/media/video/gspca/ov519.c ++++ b/drivers/media/video/gspca/ov519.c +@@ -3364,6 +3364,7 @@ static const __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 }, + {USB_DEVICE(0x041e, 0x4064), + .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, ++ {USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 }, + {USB_DEVICE(0x041e, 0x4068), + .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, + {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 }, +diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c +index 74fdc40..c1d7b88 100644 +--- a/drivers/mtd/ubi/upd.c ++++ b/drivers/mtd/ubi/upd.c +@@ -147,12 +147,14 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol, + } + + if (bytes == 0) { ++ err = ubi_wl_flush(ubi); ++ if (err) ++ return err; ++ + err = clear_update_marker(ubi, vol, 0); + if (err) + return err; +- err = ubi_wl_flush(ubi); +- if (!err) +- vol->updating = 0; ++ vol->updating = 0; + } + + vol->upd_buf = vmalloc(ubi->leb_size); +@@ -362,16 +364,16 @@ int ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol, + + ubi_assert(vol->upd_received <= vol->upd_bytes); + if (vol->upd_received == vol->upd_bytes) { ++ err = ubi_wl_flush(ubi); ++ if (err) ++ return err; + /* The update is finished, clear the update marker */ + err = clear_update_marker(ubi, vol, vol->upd_bytes); + if (err) + return err; +- err = ubi_wl_flush(ubi); +- if (err == 0) { +- vol->updating = 0; +- err = to_write; +- vfree(vol->upd_buf); +- } ++ vol->updating = 0; ++ err = to_write; ++ vfree(vol->upd_buf); + } + + return err; +diff --git a/drivers/net/b44.c b/drivers/net/b44.c +index 2a91323..4869adb 100644 +--- a/drivers/net/b44.c ++++ b/drivers/net/b44.c +@@ -1505,8 +1505,7 @@ static int b44_magic_pattern(u8 *macaddr, u8 *ppattern, u8 *pmask, int offset) + for (k = 0; k< ethaddr_bytes; k++) { + ppattern[offset + magicsync + + (j * ETH_ALEN) + k] = macaddr[k]; +- len++; +- set_bit(len, (unsigned long *) pmask); ++ set_bit(len++, (unsigned long *) pmask); + } + } + return len - 1; +diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c +index ba29dc3..d110c1b 100644 +--- a/drivers/net/bcm63xx_enet.c ++++ b/drivers/net/bcm63xx_enet.c +@@ -1248,9 +1248,15 @@ static void bcm_enet_get_drvinfo(struct net_device *netdev, + drvinfo->n_stats = BCM_ENET_STATS_LEN; + } + +-static int bcm_enet_get_stats_count(struct net_device *netdev) ++static int bcm_enet_get_sset_count(struct net_device *netdev, ++ int string_set) + { +- return BCM_ENET_STATS_LEN; ++ switch (string_set) { ++ case ETH_SS_STATS: ++ return BCM_ENET_STATS_LEN; ++ default: ++ return -EINVAL; ++ } + } + + static void bcm_enet_get_strings(struct net_device *netdev, +@@ -1476,7 +1482,7 @@ static int bcm_enet_set_pauseparam(struct net_device *dev, + + static struct ethtool_ops bcm_enet_ethtool_ops = { + .get_strings = bcm_enet_get_strings, +- .get_stats_count = bcm_enet_get_stats_count, ++ .get_sset_count = bcm_enet_get_sset_count, + .get_ethtool_stats = bcm_enet_get_ethtool_stats, + .get_settings = bcm_enet_get_settings, + .set_settings = bcm_enet_set_settings, +diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c +index 644962a..7918852 100644 +--- a/drivers/net/wireless/ath/ath5k/eeprom.c ++++ b/drivers/net/wireless/ath/ath5k/eeprom.c +@@ -97,6 +97,7 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah) + struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; + int ret; + u16 val; ++ u32 cksum, offset; + + /* + * Read values from EEPROM and store them in the capability structure +@@ -111,7 +112,6 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah) + if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0) + return 0; + +-#ifdef notyet + /* + * Validate the checksum of the EEPROM date. There are some + * devices with invalid EEPROMs. +@@ -124,7 +124,6 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah) + ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum); + return -EIO; + } +-#endif + + AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version), + ee_ant_gain); +diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c +index 1a039f2..9d67647 100644 +--- a/drivers/net/wireless/ath/ath5k/phy.c ++++ b/drivers/net/wireless/ath/ath5k/phy.c +@@ -2954,8 +2954,6 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, + ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower); + return -EINVAL; + } +- if (txpower == 0) +- txpower = AR5K_TUNE_DEFAULT_TXPOWER; + + /* Reset TX power values */ + memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower)); +diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h +index 1d59f10..cdb90c5 100644 +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -139,6 +139,7 @@ struct ath_buf { + dma_addr_t bf_daddr; /* physical addr of desc */ + dma_addr_t bf_buf_addr; /* physical addr of data buffer */ + bool bf_stale; ++ bool bf_isnullfunc; + u16 bf_flags; + struct ath_buf_state bf_state; + dma_addr_t bf_dmacontext; +@@ -524,6 +525,8 @@ struct ath_led { + #define SC_OP_BEACON_SYNC BIT(19) + #define SC_OP_BTCOEX_ENABLED BIT(20) + #define SC_OP_BT_PRIORITY_DETECTED BIT(21) ++#define SC_OP_NULLFUNC_COMPLETED BIT(22) ++#define SC_OP_PS_ENABLED BIT(23) + + struct ath_bus_ops { + void (*read_cachesize)(struct ath_softc *sc, int *csz); +diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c +index ca7694c..c7aa05a 100644 +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -937,6 +937,11 @@ int ath9k_hw_init(struct ath_hw *ah) + DPRINTF(ah->ah_sc, ATH_DBG_RESET, "serialize_regmode is %d\n", + ah->config.serialize_regmode); + ++ if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) ++ ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD >> 1; ++ else ++ ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD; ++ + if (!ath9k_hw_macversion_supported(ah->hw_version.macVersion)) { + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, + "Mac Chip Rev 0x%02x.%x is not supported by " +@@ -3670,7 +3675,11 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah) + pCap->keycache_size = AR_KEYTABLE_SIZE; + + pCap->hw_caps |= ATH9K_HW_CAP_FASTCC; +- pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD; ++ ++ if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) ++ pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD >> 1; ++ else ++ pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD; + + if (AR_SREV_9285_10_OR_LATER(ah)) + pCap->num_gpio_pins = AR9285_NUM_GPIO; +diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h +index b892345..57f1463 100644 +--- a/drivers/net/wireless/ath/ath9k/hw.h ++++ b/drivers/net/wireless/ath/ath9k/hw.h +@@ -218,6 +218,7 @@ struct ath9k_ops_config { + #define AR_SPUR_FEEQ_BOUND_HT20 10 + int spurmode; + u16 spurchans[AR_EEPROM_MODAL_SPURS][2]; ++ u8 max_txtrig_level; + }; + + enum ath9k_int { +diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c +index 800bfab..d4d9d82 100644 +--- a/drivers/net/wireless/ath/ath9k/mac.c ++++ b/drivers/net/wireless/ath/ath9k/mac.c +@@ -70,7 +70,7 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel) + u32 txcfg, curLevel, newLevel; + enum ath9k_int omask; + +- if (ah->tx_trig_level >= MAX_TX_FIFO_THRESHOLD) ++ if (ah->tx_trig_level >= ah->config.max_txtrig_level) + return false; + + omask = ath9k_hw_set_interrupts(ah, ah->mask_reg & ~ATH9K_INT_GLOBAL); +@@ -79,7 +79,7 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel) + curLevel = MS(txcfg, AR_FTRIG); + newLevel = curLevel; + if (bIncTrigLevel) { +- if (curLevel < MAX_TX_FIFO_THRESHOLD) ++ if (curLevel < ah->config.max_txtrig_level) + newLevel++; + } else if (curLevel > MIN_TX_FIFO_THRESHOLD) + newLevel--; +@@ -222,6 +222,8 @@ int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds) + ds->ds_txstat.ts_status = 0; + ds->ds_txstat.ts_flags = 0; + ++ if (ads->ds_txstatus1 & AR_FrmXmitOK) ++ ds->ds_txstat.ts_status |= ATH9K_TX_ACKED; + if (ads->ds_txstatus1 & AR_ExcessiveRetries) + ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY; + if (ads->ds_txstatus1 & AR_Filtered) +diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h +index f56e77d..ff65f85 100644 +--- a/drivers/net/wireless/ath/ath9k/mac.h ++++ b/drivers/net/wireless/ath/ath9k/mac.h +@@ -76,6 +76,7 @@ + #define ATH9K_TXERR_FIFO 0x04 + #define ATH9K_TXERR_XTXOP 0x08 + #define ATH9K_TXERR_TIMER_EXPIRED 0x10 ++#define ATH9K_TX_ACKED 0x20 + + #define ATH9K_TX_BA 0x01 + #define ATH9K_TX_PWRMGMT 0x02 +diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c +index 43d2be9..59359e3 100644 +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -2327,6 +2327,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) + + if (changed & IEEE80211_CONF_CHANGE_PS) { + if (conf->flags & IEEE80211_CONF_PS) { ++ sc->sc_flags |= SC_OP_PS_ENABLED; + if (!(ah->caps.hw_caps & + ATH9K_HW_CAP_AUTOSLEEP)) { + if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) { +@@ -2334,11 +2335,17 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) + ath9k_hw_set_interrupts(sc->sc_ah, + sc->imask); + } +- ath9k_hw_setrxabort(sc->sc_ah, 1); + } + sc->ps_enabled = true; ++ if ((sc->sc_flags & SC_OP_NULLFUNC_COMPLETED)) { ++ sc->sc_flags &= ~SC_OP_NULLFUNC_COMPLETED; ++ sc->ps_enabled = true; ++ ath9k_hw_setrxabort(sc->sc_ah, 1); ++ } + } else { + sc->ps_enabled = false; ++ sc->sc_flags &= ~(SC_OP_PS_ENABLED | ++ SC_OP_NULLFUNC_COMPLETED); + ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); + if (!(ah->caps.hw_caps & + ATH9K_HW_CAP_AUTOSLEEP)) { +diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c +index 42551a4..4753909 100644 +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -1592,6 +1592,13 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, + } + + bf->bf_buf_addr = bf->bf_dmacontext; ++ ++ if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc)) { ++ bf->bf_isnullfunc = true; ++ sc->sc_flags &= ~SC_OP_NULLFUNC_COMPLETED; ++ } else ++ bf->bf_isnullfunc = false; ++ + return 0; + } + +@@ -1989,6 +1996,15 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) + if (ds == txq->axq_gatingds) + txq->axq_gatingds = NULL; + ++ if (bf->bf_isnullfunc && ++ (ds->ds_txstat.ts_status & ATH9K_TX_ACKED)) { ++ if ((sc->sc_flags & SC_OP_PS_ENABLED)) { ++ sc->ps_enabled = true; ++ ath9k_hw_setrxabort(sc->sc_ah, 1); ++ } else ++ sc->sc_flags |= SC_OP_NULLFUNC_COMPLETED; ++ } ++ + /* + * Remove ath_buf's of the same transmit unit from txq, + * however leave the last descriptor back as the holding +@@ -2004,7 +2020,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) + if (bf_isaggr(bf)) + txq->axq_aggr_depth--; + +- txok = (ds->ds_txstat.ts_status == 0); ++ txok = !(ds->ds_txstat.ts_status & ATH9K_TXERR_FILT); + txq->axq_tx_inprogress = false; + spin_unlock_bh(&txq->axq_lock); + +@@ -2065,7 +2081,9 @@ static void ath_tx_complete_poll_work(struct work_struct *work) + + if (needreset) { + DPRINTF(sc, ATH_DBG_RESET, "tx hung, resetting the chip\n"); ++ ath9k_ps_wakeup(sc); + ath_reset(sc, false); ++ ath9k_ps_restore(sc); + } + + ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, +diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c +index 8783022..d579df7 100644 +--- a/drivers/net/wireless/b43legacy/rfkill.c ++++ b/drivers/net/wireless/b43legacy/rfkill.c +@@ -34,6 +34,13 @@ bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) + & B43legacy_MMIO_RADIO_HWENABLED_HI_MASK)) + return 1; + } else { ++ /* To prevent CPU fault on PPC, do not read a register ++ * unless the interface is started; however, on resume ++ * for hibernation, this routine is entered early. When ++ * that happens, unconditionally return TRUE. ++ */ ++ if (b43legacy_status(dev) < B43legacy_STAT_STARTED) ++ return 1; + if (b43legacy_read16(dev, B43legacy_MMIO_RADIO_HWENABLED_LO) + & B43legacy_MMIO_RADIO_HWENABLED_LO_MASK) + return 1; +diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c +index 6e2fc0c..43102bf 100644 +--- a/drivers/net/wireless/ipw2x00/ipw2100.c ++++ b/drivers/net/wireless/ipw2x00/ipw2100.c +@@ -6487,6 +6487,16 @@ static int ipw2100_resume(struct pci_dev *pci_dev) + } + #endif + ++static void ipw2100_shutdown(struct pci_dev *pci_dev) ++{ ++ struct ipw2100_priv *priv = pci_get_drvdata(pci_dev); ++ ++ /* Take down the device; powers it off, etc. */ ++ ipw2100_down(priv); ++ ++ pci_disable_device(pci_dev); ++} ++ + #define IPW2100_DEV_ID(x) { PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, x } + + static struct pci_device_id ipw2100_pci_id_table[] __devinitdata = { +@@ -6550,6 +6560,7 @@ static struct pci_driver ipw2100_pci_driver = { + .suspend = ipw2100_suspend, + .resume = ipw2100_resume, + #endif ++ .shutdown = ipw2100_shutdown, + }; + + /** +diff --git a/drivers/net/wireless/rtl818x/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187.h +index bf9175a..99406bf 100644 +--- a/drivers/net/wireless/rtl818x/rtl8187.h ++++ b/drivers/net/wireless/rtl818x/rtl8187.h +@@ -23,6 +23,7 @@ + #define RTL8187_EEPROM_TXPWR_CHAN_1 0x16 /* 3 channels */ + #define RTL8187_EEPROM_TXPWR_CHAN_6 0x1B /* 2 channels */ + #define RTL8187_EEPROM_TXPWR_CHAN_4 0x3D /* 2 channels */ ++#define RTL8187_EEPROM_SELECT_GPIO 0x3B + + #define RTL8187_REQT_READ 0xC0 + #define RTL8187_REQT_WRITE 0x40 +@@ -31,6 +32,9 @@ + + #define RTL8187_MAX_RX 0x9C4 + ++#define RFKILL_MASK_8187_89_97 0x2 ++#define RFKILL_MASK_8198 0x4 ++ + struct rtl8187_rx_info { + struct urb *urb; + struct ieee80211_hw *dev; +@@ -123,6 +127,7 @@ struct rtl8187_priv { + u8 noise; + u8 slot_time; + u8 aifsn[4]; ++ u8 rfkill_mask; + struct { + __le64 buf; + struct sk_buff_head queue; +diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c +index 2017ccc..ea49918 100644 +--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c ++++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c +@@ -1329,6 +1329,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, + struct ieee80211_channel *channel; + const char *chip_name; + u16 txpwr, reg; ++ u16 product_id = le16_to_cpu(udev->descriptor.idProduct); + int err, i; + + dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8187_ops); +@@ -1488,6 +1489,13 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, + (*channel++).hw_value = txpwr & 0xFF; + (*channel++).hw_value = txpwr >> 8; + } ++ /* Handle the differing rfkill GPIO bit in different models */ ++ priv->rfkill_mask = RFKILL_MASK_8187_89_97; ++ if (product_id == 0x8197 || product_id == 0x8198) { ++ eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_SELECT_GPIO, ®); ++ if (reg & 0xFF00) ++ priv->rfkill_mask = RFKILL_MASK_8198; ++ } + + /* + * XXX: Once this driver supports anything that requires +@@ -1516,9 +1524,9 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, + mutex_init(&priv->conf_mutex); + skb_queue_head_init(&priv->b_tx_status.queue); + +- printk(KERN_INFO "%s: hwaddr %pM, %s V%d + %s\n", ++ printk(KERN_INFO "%s: hwaddr %pM, %s V%d + %s, rfkill mask %d\n", + wiphy_name(dev->wiphy), dev->wiphy->perm_addr, +- chip_name, priv->asic_rev, priv->rf->name); ++ chip_name, priv->asic_rev, priv->rf->name, priv->rfkill_mask); + + #ifdef CONFIG_RTL8187_LEDS + eeprom_93cx6_read(&eeprom, 0x3F, ®); +diff --git a/drivers/net/wireless/rtl818x/rtl8187_rfkill.c b/drivers/net/wireless/rtl818x/rtl8187_rfkill.c +index cad8037..03555e1 100644 +--- a/drivers/net/wireless/rtl818x/rtl8187_rfkill.c ++++ b/drivers/net/wireless/rtl818x/rtl8187_rfkill.c +@@ -25,10 +25,10 @@ static bool rtl8187_is_radio_enabled(struct rtl8187_priv *priv) + u8 gpio; + + gpio = rtl818x_ioread8(priv, &priv->map->GPIO0); +- rtl818x_iowrite8(priv, &priv->map->GPIO0, gpio & ~0x02); ++ rtl818x_iowrite8(priv, &priv->map->GPIO0, gpio & ~priv->rfkill_mask); + gpio = rtl818x_ioread8(priv, &priv->map->GPIO1); + +- return gpio & 0x02; ++ return gpio & priv->rfkill_mask; + } + + void rtl8187_rfkill_init(struct ieee80211_hw *hw) +diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c +index b952ebc..5753036 100644 +--- a/drivers/pci/dmar.c ++++ b/drivers/pci/dmar.c +@@ -582,6 +582,8 @@ int __init dmar_table_init(void) + return 0; + } + ++static int bios_warned; ++ + int __init check_zero_address(void) + { + struct acpi_table_dmar *dmar; +@@ -601,6 +603,9 @@ int __init check_zero_address(void) + } + + if (entry_header->type == ACPI_DMAR_TYPE_HARDWARE_UNIT) { ++ void __iomem *addr; ++ u64 cap, ecap; ++ + drhd = (void *)entry_header; + if (!drhd->address) { + /* Promote an attitude of violence to a BIOS engineer today */ +@@ -609,17 +614,40 @@ int __init check_zero_address(void) + dmi_get_system_info(DMI_BIOS_VENDOR), + dmi_get_system_info(DMI_BIOS_VERSION), + dmi_get_system_info(DMI_PRODUCT_VERSION)); +-#ifdef CONFIG_DMAR +- dmar_disabled = 1; +-#endif +- return 0; ++ bios_warned = 1; ++ goto failed; ++ } ++ ++ addr = early_ioremap(drhd->address, VTD_PAGE_SIZE); ++ if (!addr ) { ++ printk("IOMMU: can't validate: %llx\n", drhd->address); ++ goto failed; ++ } ++ cap = dmar_readq(addr + DMAR_CAP_REG); ++ ecap = dmar_readq(addr + DMAR_ECAP_REG); ++ early_iounmap(addr, VTD_PAGE_SIZE); ++ if (cap == (uint64_t)-1 && ecap == (uint64_t)-1) { ++ /* Promote an attitude of violence to a BIOS engineer today */ ++ WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n" ++ "BIOS vendor: %s; Ver: %s; Product Version: %s\n", ++ drhd->address, ++ dmi_get_system_info(DMI_BIOS_VENDOR), ++ dmi_get_system_info(DMI_BIOS_VERSION), ++ dmi_get_system_info(DMI_PRODUCT_VERSION)); ++ bios_warned = 1; ++ goto failed; + } +- break; + } + + entry_header = ((void *)entry_header + entry_header->length); + } + return 1; ++ ++failed: ++#ifdef CONFIG_DMAR ++ dmar_disabled = 1; ++#endif ++ return 0; + } + + void __init detect_intel_iommu(void) +@@ -664,6 +692,18 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) + int agaw = 0; + int msagaw = 0; + ++ if (!drhd->reg_base_addr) { ++ if (!bios_warned) { ++ WARN(1, "Your BIOS is broken; DMAR reported at address zero!\n" ++ "BIOS vendor: %s; Ver: %s; Product Version: %s\n", ++ dmi_get_system_info(DMI_BIOS_VENDOR), ++ dmi_get_system_info(DMI_BIOS_VERSION), ++ dmi_get_system_info(DMI_PRODUCT_VERSION)); ++ bios_warned = 1; ++ } ++ return -EINVAL; ++ } ++ + iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); + if (!iommu) + return -ENOMEM; +@@ -680,13 +720,16 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) + iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); + + if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) { +- /* Promote an attitude of violence to a BIOS engineer today */ +- WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n" +- "BIOS vendor: %s; Ver: %s; Product Version: %s\n", +- drhd->reg_base_addr, +- dmi_get_system_info(DMI_BIOS_VENDOR), +- dmi_get_system_info(DMI_BIOS_VERSION), +- dmi_get_system_info(DMI_PRODUCT_VERSION)); ++ if (!bios_warned) { ++ /* Promote an attitude of violence to a BIOS engineer today */ ++ WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n" ++ "BIOS vendor: %s; Ver: %s; Product Version: %s\n", ++ drhd->reg_base_addr, ++ dmi_get_system_info(DMI_BIOS_VENDOR), ++ dmi_get_system_info(DMI_BIOS_VERSION), ++ dmi_get_system_info(DMI_PRODUCT_VERSION)); ++ bios_warned = 1; ++ } + goto err_unmap; + } + +diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c +index 1840a05..2498602 100644 +--- a/drivers/pci/intel-iommu.c ++++ b/drivers/pci/intel-iommu.c +@@ -1523,12 +1523,15 @@ static int domain_context_mapping_one(struct dmar_domain *domain, int segment, + + /* Skip top levels of page tables for + * iommu which has less agaw than default. ++ * Unnecessary for PT mode. + */ +- for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) { +- pgd = phys_to_virt(dma_pte_addr(pgd)); +- if (!dma_pte_present(pgd)) { +- spin_unlock_irqrestore(&iommu->lock, flags); +- return -ENOMEM; ++ if (translation != CONTEXT_TT_PASS_THROUGH) { ++ for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) { ++ pgd = phys_to_virt(dma_pte_addr(pgd)); ++ if (!dma_pte_present(pgd)) { ++ spin_unlock_irqrestore(&iommu->lock, flags); ++ return -ENOMEM; ++ } + } + } + } +@@ -1991,6 +1994,16 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev, + "IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n", + pci_name(pdev), start, end); + ++ if (end < start) { ++ WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n" ++ "BIOS vendor: %s; Ver: %s; Product Version: %s\n", ++ dmi_get_system_info(DMI_BIOS_VENDOR), ++ dmi_get_system_info(DMI_BIOS_VERSION), ++ dmi_get_system_info(DMI_PRODUCT_VERSION)); ++ ret = -EIO; ++ goto error; ++ } ++ + if (end >> agaw_to_width(domain->agaw)) { + WARN(1, "Your BIOS is broken; RMRR exceeds permitted address width (%d bits)\n" + "BIOS vendor: %s; Ver: %s; Product Version: %s\n", +@@ -3228,6 +3241,9 @@ static int device_notifier(struct notifier_block *nb, + struct pci_dev *pdev = to_pci_dev(dev); + struct dmar_domain *domain; + ++ if (iommu_no_mapping(dev)) ++ return 0; ++ + domain = find_domain(pdev); + if (!domain) + return 0; +diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c +index ab64522..d8b4229 100644 +--- a/drivers/platform/x86/acerhdf.c ++++ b/drivers/platform/x86/acerhdf.c +@@ -52,7 +52,7 @@ + */ + #undef START_IN_KERNEL_MODE + +-#define DRV_VER "0.5.18" ++#define DRV_VER "0.5.20" + + /* + * According to the Atom N270 datasheet, +@@ -112,12 +112,14 @@ module_param_string(force_product, force_product, 16, 0); + MODULE_PARM_DESC(force_product, "Force BIOS product and omit BIOS check"); + + /* +- * cmd_off: to switch the fan completely off / to check if the fan is off ++ * cmd_off: to switch the fan completely off ++ * chk_off: to check if the fan is off + * cmd_auto: to set the BIOS in control of the fan. The BIOS regulates then + * the fan speed depending on the temperature + */ + struct fancmd { + u8 cmd_off; ++ u8 chk_off; + u8 cmd_auto; + }; + +@@ -134,32 +136,41 @@ struct bios_settings_t { + /* Register addresses and values for different BIOS versions */ + static const struct bios_settings_t bios_tbl[] = { + /* AOA110 */ +- {"Acer", "AOA110", "v0.3109", 0x55, 0x58, {0x1f, 0x00} }, +- {"Acer", "AOA110", "v0.3114", 0x55, 0x58, {0x1f, 0x00} }, +- {"Acer", "AOA110", "v0.3301", 0x55, 0x58, {0xaf, 0x00} }, +- {"Acer", "AOA110", "v0.3304", 0x55, 0x58, {0xaf, 0x00} }, +- {"Acer", "AOA110", "v0.3305", 0x55, 0x58, {0xaf, 0x00} }, +- {"Acer", "AOA110", "v0.3307", 0x55, 0x58, {0xaf, 0x00} }, +- {"Acer", "AOA110", "v0.3308", 0x55, 0x58, {0x21, 0x00} }, +- {"Acer", "AOA110", "v0.3309", 0x55, 0x58, {0x21, 0x00} }, +- {"Acer", "AOA110", "v0.3310", 0x55, 0x58, {0x21, 0x00} }, ++ {"Acer", "AOA110", "v0.3109", 0x55, 0x58, {0x1f, 0x1f, 0x00} }, ++ {"Acer", "AOA110", "v0.3114", 0x55, 0x58, {0x1f, 0x1f, 0x00} }, ++ {"Acer", "AOA110", "v0.3301", 0x55, 0x58, {0xaf, 0xaf, 0x00} }, ++ {"Acer", "AOA110", "v0.3304", 0x55, 0x58, {0xaf, 0xaf, 0x00} }, ++ {"Acer", "AOA110", "v0.3305", 0x55, 0x58, {0xaf, 0xaf, 0x00} }, ++ {"Acer", "AOA110", "v0.3307", 0x55, 0x58, {0xaf, 0xaf, 0x00} }, ++ {"Acer", "AOA110", "v0.3308", 0x55, 0x58, {0x21, 0x21, 0x00} }, ++ {"Acer", "AOA110", "v0.3309", 0x55, 0x58, {0x21, 0x21, 0x00} }, ++ {"Acer", "AOA110", "v0.3310", 0x55, 0x58, {0x21, 0x21, 0x00} }, + /* AOA150 */ +- {"Acer", "AOA150", "v0.3114", 0x55, 0x58, {0x20, 0x00} }, +- {"Acer", "AOA150", "v0.3301", 0x55, 0x58, {0x20, 0x00} }, +- {"Acer", "AOA150", "v0.3304", 0x55, 0x58, {0x20, 0x00} }, +- {"Acer", "AOA150", "v0.3305", 0x55, 0x58, {0x20, 0x00} }, +- {"Acer", "AOA150", "v0.3307", 0x55, 0x58, {0x20, 0x00} }, +- {"Acer", "AOA150", "v0.3308", 0x55, 0x58, {0x20, 0x00} }, +- {"Acer", "AOA150", "v0.3309", 0x55, 0x58, {0x20, 0x00} }, +- {"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x00} }, ++ {"Acer", "AOA150", "v0.3114", 0x55, 0x58, {0x20, 0x20, 0x00} }, ++ {"Acer", "AOA150", "v0.3301", 0x55, 0x58, {0x20, 0x20, 0x00} }, ++ {"Acer", "AOA150", "v0.3304", 0x55, 0x58, {0x20, 0x20, 0x00} }, ++ {"Acer", "AOA150", "v0.3305", 0x55, 0x58, {0x20, 0x20, 0x00} }, ++ {"Acer", "AOA150", "v0.3307", 0x55, 0x58, {0x20, 0x20, 0x00} }, ++ {"Acer", "AOA150", "v0.3308", 0x55, 0x58, {0x20, 0x20, 0x00} }, ++ {"Acer", "AOA150", "v0.3309", 0x55, 0x58, {0x20, 0x20, 0x00} }, ++ {"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x20, 0x00} }, ++ /* Acer 1410 */ ++ {"Acer", "Aspire 1410", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, + /* special BIOS / other */ +- {"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x00} }, +- {"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x00} }, +- {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00} }, +- {"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x00} }, +- {"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} }, ++ {"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x21, 0x00} }, ++ {"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x20, 0x00} }, ++ {"Gateway ", "LT31 ", "v1.3103 ", 0x55, 0x58, ++ {0x10, 0x0f, 0x00} }, ++ {"Gateway ", "LT31 ", "v1.3201 ", 0x55, 0x58, ++ {0x10, 0x0f, 0x00} }, ++ {"Gateway ", "LT31 ", "v1.3302 ", 0x55, 0x58, ++ {0x10, 0x0f, 0x00} }, ++ {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x21, 0x00} }, ++ {"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x20, 0x00} }, ++ {"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x21, 0x00} }, ++ {"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x20, 0x00} }, + /* pewpew-terminator */ +- {"", "", "", 0, 0, {0, 0} } ++ {"", "", "", 0, 0, {0, 0, 0} } + }; + + static const struct bios_settings_t *bios_cfg __read_mostly; +@@ -183,7 +194,7 @@ static int acerhdf_get_fanstate(int *state) + if (ec_read(bios_cfg->fanreg, &fan)) + return -EINVAL; + +- if (fan != bios_cfg->cmd.cmd_off) ++ if (fan != bios_cfg->cmd.chk_off) + *state = ACERHDF_FAN_AUTO; + else + *state = ACERHDF_FAN_OFF; +diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c +index b39d2bb..849359a 100644 +--- a/drivers/platform/x86/asus-laptop.c ++++ b/drivers/platform/x86/asus-laptop.c +@@ -1283,8 +1283,8 @@ static int asus_hotk_add(struct acpi_device *device) + hotk->ledd_status = 0xFFF; + + /* Set initial values of light sensor and level */ +- hotk->light_switch = 1; /* Default to light sensor disabled */ +- hotk->light_level = 0; /* level 5 for sensor sensitivity */ ++ hotk->light_switch = 0; /* Default to light sensor disabled */ ++ hotk->light_level = 5; /* level 5 for sensor sensitivity */ + + if (ls_switch_handle) + set_light_sens_switch(hotk->light_switch); +diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c +index a848c7e..1ee734c 100644 +--- a/drivers/platform/x86/thinkpad_acpi.c ++++ b/drivers/platform/x86/thinkpad_acpi.c +@@ -3866,15 +3866,6 @@ enum { + + #define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw" + +-static void bluetooth_suspend(pm_message_t state) +-{ +- /* Try to make sure radio will resume powered off */ +- if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd", +- TP_ACPI_BLTH_PWR_OFF_ON_RESUME)) +- vdbg_printk(TPACPI_DBG_RFKILL, +- "bluetooth power down on resume request failed\n"); +-} +- + static int bluetooth_get_status(void) + { + int status; +@@ -3908,10 +3899,9 @@ static int bluetooth_set_status(enum tpacpi_rfkill_state state) + #endif + + /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */ ++ status = TP_ACPI_BLUETOOTH_RESUMECTRL; + if (state == TPACPI_RFK_RADIO_ON) +- status = TP_ACPI_BLUETOOTH_RADIOSSW; +- else +- status = 0; ++ status |= TP_ACPI_BLUETOOTH_RADIOSSW; + + if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status)) + return -EIO; +@@ -4050,7 +4040,6 @@ static struct ibm_struct bluetooth_driver_data = { + .read = bluetooth_read, + .write = bluetooth_write, + .exit = bluetooth_exit, +- .suspend = bluetooth_suspend, + .shutdown = bluetooth_shutdown, + }; + +@@ -4068,15 +4057,6 @@ enum { + + #define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw" + +-static void wan_suspend(pm_message_t state) +-{ +- /* Try to make sure radio will resume powered off */ +- if (!acpi_evalf(NULL, NULL, "\\WGSV", "qvd", +- TP_ACPI_WGSV_PWR_OFF_ON_RESUME)) +- vdbg_printk(TPACPI_DBG_RFKILL, +- "WWAN power down on resume request failed\n"); +-} +- + static int wan_get_status(void) + { + int status; +@@ -4109,11 +4089,10 @@ static int wan_set_status(enum tpacpi_rfkill_state state) + } + #endif + +- /* We make sure to keep TP_ACPI_WANCARD_RESUMECTRL off */ ++ /* We make sure to set TP_ACPI_WANCARD_RESUMECTRL */ ++ status = TP_ACPI_WANCARD_RESUMECTRL; + if (state == TPACPI_RFK_RADIO_ON) +- status = TP_ACPI_WANCARD_RADIOSSW; +- else +- status = 0; ++ status |= TP_ACPI_WANCARD_RADIOSSW; + + if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status)) + return -EIO; +@@ -4251,7 +4230,6 @@ static struct ibm_struct wan_driver_data = { + .read = wan_read, + .write = wan_write, + .exit = wan_exit, +- .suspend = wan_suspend, + .shutdown = wan_shutdown, + }; + +@@ -6123,8 +6101,8 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = { + + /* Models with Intel Extreme Graphics 2 */ + TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC), +- TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC), +- TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC), ++ TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), ++ TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), + + /* Models with Intel GMA900 */ + TPACPI_Q_IBM('7', '0', TPACPI_BRGHT_Q_NOEC), /* T43, R52 */ +diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c +index 737b4c9..807042b 100644 +--- a/drivers/serial/8250.c ++++ b/drivers/serial/8250.c +@@ -1339,14 +1339,12 @@ static void serial8250_start_tx(struct uart_port *port) + serial_out(up, UART_IER, up->ier); + + if (up->bugs & UART_BUG_TXEN) { +- unsigned char lsr, iir; ++ unsigned char lsr; + lsr = serial_in(up, UART_LSR); + up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; +- iir = serial_in(up, UART_IIR) & 0x0f; + if ((up->port.type == PORT_RM9000) ? +- (lsr & UART_LSR_THRE && +- (iir == UART_IIR_NO_INT || iir == UART_IIR_THRI)) : +- (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT)) ++ (lsr & UART_LSR_THRE) : ++ (lsr & UART_LSR_TEMT)) + transmit_chars(up); + } + } +diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c +index 8943015..eb70843 100644 +--- a/drivers/ssb/sprom.c ++++ b/drivers/ssb/sprom.c +@@ -13,6 +13,8 @@ + + #include "ssb_private.h" + ++#include ++ + + static const struct ssb_sprom *fallback_sprom; + +@@ -33,17 +35,27 @@ static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len, + static int hex2sprom(u16 *sprom, const char *dump, size_t len, + size_t sprom_size_words) + { +- char tmp[5] = { 0 }; +- int cnt = 0; ++ char c, tmp[5] = { 0 }; ++ int err, cnt = 0; + unsigned long parsed; + +- if (len < sprom_size_words * 2) ++ /* Strip whitespace at the end. */ ++ while (len) { ++ c = dump[len - 1]; ++ if (!isspace(c) && c != '\0') ++ break; ++ len--; ++ } ++ /* Length must match exactly. */ ++ if (len != sprom_size_words * 4) + return -EINVAL; + + while (cnt < sprom_size_words) { + memcpy(tmp, dump, 4); + dump += 4; +- parsed = simple_strtoul(tmp, NULL, 16); ++ err = strict_strtoul(tmp, 16, &parsed); ++ if (err) ++ return err; + sprom[cnt++] = swab16((u16)parsed); + } + +diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c +index 2473cf0..d9461c9 100644 +--- a/drivers/usb/class/usbtmc.c ++++ b/drivers/usb/class/usbtmc.c +@@ -562,10 +562,16 @@ static ssize_t usbtmc_write(struct file *filp, const char __user *buf, + n_bytes = roundup(12 + this_part, 4); + memset(buffer + 12 + this_part, 0, n_bytes - (12 + this_part)); + +- retval = usb_bulk_msg(data->usb_dev, +- usb_sndbulkpipe(data->usb_dev, +- data->bulk_out), +- buffer, n_bytes, &actual, USBTMC_TIMEOUT); ++ do { ++ retval = usb_bulk_msg(data->usb_dev, ++ usb_sndbulkpipe(data->usb_dev, ++ data->bulk_out), ++ buffer, n_bytes, ++ &actual, USBTMC_TIMEOUT); ++ if (retval != 0) ++ break; ++ n_bytes -= actual; ++ } while (n_bytes); + + data->bTag_last_write = data->bTag; + data->bTag++; +diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c +index b1b85ab..52e5e31 100644 +--- a/drivers/usb/core/usb.c ++++ b/drivers/usb/core/usb.c +@@ -132,7 +132,7 @@ EXPORT_SYMBOL_GPL(usb_altnum_to_altsetting); + + struct find_interface_arg { + int minor; +- struct usb_interface *interface; ++ struct device_driver *drv; + }; + + static int __find_interface(struct device *dev, void *data) +@@ -143,12 +143,10 @@ static int __find_interface(struct device *dev, void *data) + if (!is_usb_interface(dev)) + return 0; + ++ if (dev->driver != arg->drv) ++ return 0; + intf = to_usb_interface(dev); +- if (intf->minor != -1 && intf->minor == arg->minor) { +- arg->interface = intf; +- return 1; +- } +- return 0; ++ return intf->minor == arg->minor; + } + + /** +@@ -156,21 +154,24 @@ static int __find_interface(struct device *dev, void *data) + * @drv: the driver whose current configuration is considered + * @minor: the minor number of the desired device + * +- * This walks the driver device list and returns a pointer to the interface +- * with the matching minor. Note, this only works for devices that share the +- * USB major number. ++ * This walks the bus device list and returns a pointer to the interface ++ * with the matching minor and driver. Note, this only works for devices ++ * that share the USB major number. + */ + struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor) + { + struct find_interface_arg argb; +- int retval; ++ struct device *dev; + + argb.minor = minor; +- argb.interface = NULL; +- /* eat the error, it will be in argb.interface */ +- retval = driver_for_each_device(&drv->drvwrap.driver, NULL, &argb, +- __find_interface); +- return argb.interface; ++ argb.drv = &drv->drvwrap.driver; ++ ++ dev = bus_find_device(&usb_bus_type, NULL, &argb, __find_interface); ++ ++ /* Drop reference count from bus_find_device */ ++ put_device(dev); ++ ++ return dev ? to_usb_interface(dev) : NULL; + } + EXPORT_SYMBOL_GPL(usb_find_interface); + +diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c +index 522efb3..1c44b97 100644 +--- a/drivers/usb/musb/musb_gadget_ep0.c ++++ b/drivers/usb/musb/musb_gadget_ep0.c +@@ -199,7 +199,6 @@ service_in_request(struct musb *musb, const struct usb_ctrlrequest *ctrlrequest) + static void musb_g_ep0_giveback(struct musb *musb, struct usb_request *req) + { + musb_g_giveback(&musb->endpoints[0].ep_in, req, 0); +- musb->ep0_state = MUSB_EP0_STAGE_SETUP; + } + + /* +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 0577e4b..dffc8a1 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -580,12 +580,48 @@ static struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0086, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0104, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0106, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0108, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0117, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0122, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0128, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0142, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0143, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0144, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0145, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0146, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0148, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0149, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0150, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0151, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0153, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0154, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0155, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0156, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0159, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0160, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, /* ZTE CDMA products */ + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0027, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0060, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 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) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, +@@ -599,6 +635,7 @@ static struct usb_device_id option_ids[] = { + { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) }, + { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ + { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) }, ++ { USB_DEVICE(ALINK_VENDOR_ID, 0xce16) }, + { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, + { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) }, + { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, +diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c +index 589f6b4..cc313d1 100644 +--- a/drivers/usb/storage/transport.c ++++ b/drivers/usb/storage/transport.c +@@ -666,10 +666,11 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) + * to wait for at least one CHECK_CONDITION to determine + * SANE_SENSE support + */ +- if ((srb->cmnd[0] == ATA_16 || srb->cmnd[0] == ATA_12) && ++ if (unlikely((srb->cmnd[0] == ATA_16 || srb->cmnd[0] == ATA_12) && + result == USB_STOR_TRANSPORT_GOOD && + !(us->fflags & US_FL_SANE_SENSE) && +- !(srb->cmnd[2] & 0x20)) { ++ !(us->fflags & US_FL_BAD_SENSE) && ++ !(srb->cmnd[2] & 0x20))) { + US_DEBUGP("-- SAT supported, increasing auto-sense\n"); + us->fflags |= US_FL_SANE_SENSE; + } +@@ -718,6 +719,12 @@ Retry_Sense: + if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) { + US_DEBUGP("-- auto-sense aborted\n"); + srb->result = DID_ABORT << 16; ++ ++ /* If SANE_SENSE caused this problem, disable it */ ++ if (sense_size != US_SENSE_SIZE) { ++ us->fflags &= ~US_FL_SANE_SENSE; ++ us->fflags |= US_FL_BAD_SENSE; ++ } + goto Handle_Errors; + } + +@@ -727,10 +734,11 @@ Retry_Sense: + * (small) sense request. This fixes some USB GSM modems + */ + if (temp_result == USB_STOR_TRANSPORT_FAILED && +- (us->fflags & US_FL_SANE_SENSE) && +- sense_size != US_SENSE_SIZE) { ++ sense_size != US_SENSE_SIZE) { + US_DEBUGP("-- auto-sense failure, retry small sense\n"); + sense_size = US_SENSE_SIZE; ++ us->fflags &= ~US_FL_SANE_SENSE; ++ us->fflags |= US_FL_BAD_SENSE; + goto Retry_Sense; + } + +@@ -754,6 +762,7 @@ Retry_Sense: + */ + if (srb->sense_buffer[7] > (US_SENSE_SIZE - 8) && + !(us->fflags & US_FL_SANE_SENSE) && ++ !(us->fflags & US_FL_BAD_SENSE) && + (srb->sense_buffer[0] & 0x7C) == 0x70) { + US_DEBUGP("-- SANE_SENSE support enabled\n"); + us->fflags |= US_FL_SANE_SENSE; +diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h +index d4f034e..64a0a2c 100644 +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -818,6 +818,13 @@ UNUSUAL_DEV( 0x066f, 0x8000, 0x0001, 0x0001, + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + ++/* Reported by Daniel Kukula */ ++UNUSUAL_DEV( 0x067b, 0x1063, 0x0100, 0x0100, ++ "Prolific Technology, Inc.", ++ "Prolific Storage Gadget", ++ US_SC_DEVICE, US_PR_DEVICE, NULL, ++ US_FL_BAD_SENSE ), ++ + /* Reported by Rogerio Brito */ + UNUSUAL_DEV( 0x067b, 0x2317, 0x0001, 0x001, + "Prolific Technology, Inc.", +diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c +index 8060b85..716c8d7 100644 +--- a/drivers/usb/storage/usb.c ++++ b/drivers/usb/storage/usb.c +@@ -228,6 +228,7 @@ void fill_inquiry_response(struct us_data *us, unsigned char *data, + if (data_len<36) // You lose. + return; + ++ memset(data+8, ' ', 28); + if(data[0]&0x20) { /* USB device currently not connected. Return + peripheral qualifier 001b ("...however, the + physical device is not currently connected +@@ -237,15 +238,15 @@ void fill_inquiry_response(struct us_data *us, unsigned char *data, + device, it may return zeros or ASCII spaces + (20h) in those fields until the data is + available from the device."). */ +- memset(data+8,0,28); + } else { + u16 bcdDevice = le16_to_cpu(us->pusb_dev->descriptor.bcdDevice); +- memcpy(data+8, us->unusual_dev->vendorName, +- strlen(us->unusual_dev->vendorName) > 8 ? 8 : +- strlen(us->unusual_dev->vendorName)); +- memcpy(data+16, us->unusual_dev->productName, +- strlen(us->unusual_dev->productName) > 16 ? 16 : +- strlen(us->unusual_dev->productName)); ++ int n; ++ ++ n = strlen(us->unusual_dev->vendorName); ++ memcpy(data+8, us->unusual_dev->vendorName, min(8, n)); ++ n = strlen(us->unusual_dev->productName); ++ memcpy(data+16, us->unusual_dev->productName, min(16, n)); ++ + data[32] = 0x30 + ((bcdDevice>>12) & 0x0F); + data[33] = 0x30 + ((bcdDevice>>8) & 0x0F); + data[34] = 0x30 + ((bcdDevice>>4) & 0x0F); +@@ -459,6 +460,9 @@ static void adjust_quirks(struct us_data *us) + case 'a': + f |= US_FL_SANE_SENSE; + break; ++ case 'b': ++ f |= US_FL_BAD_SENSE; ++ break; + case 'c': + f |= US_FL_FIX_CAPACITY; + break; +diff --git a/drivers/video/matrox/g450_pll.c b/drivers/video/matrox/g450_pll.c +index 09f6e04..c15f8a5 100644 +--- a/drivers/video/matrox/g450_pll.c ++++ b/drivers/video/matrox/g450_pll.c +@@ -368,7 +368,8 @@ static int __g450_setclk(struct matrox_fb_info *minfo, unsigned int fout, + M1064_XDVICLKCTRL_C1DVICLKEN | + M1064_XDVICLKCTRL_DVILOOPCTL | + M1064_XDVICLKCTRL_P1LOOPBWDTCTL; +- matroxfb_DAC_out(minfo, M1064_XDVICLKCTRL, tmp); ++ /* Setting this breaks PC systems so don't do it */ ++ /* matroxfb_DAC_out(minfo, M1064_XDVICLKCTRL, tmp); */ + matroxfb_DAC_out(minfo, M1064_XPWRCTRL, + xpwrctrl); + +diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c +index d31505b..4204336 100644 +--- a/drivers/xen/balloon.c ++++ b/drivers/xen/balloon.c +@@ -66,8 +66,6 @@ struct balloon_stats { + /* We aim for 'current allocation' == 'target allocation'. */ + unsigned long current_pages; + unsigned long target_pages; +- /* We may hit the hard limit in Xen. If we do then we remember it. */ +- unsigned long hard_limit; + /* + * Drivers may alter the memory reservation independently, but they + * must inform the balloon driver so we avoid hitting the hard limit. +@@ -136,6 +134,8 @@ static void balloon_append(struct page *page) + list_add(&page->lru, &ballooned_pages); + balloon_stats.balloon_low++; + } ++ ++ totalram_pages--; + } + + /* balloon_retrieve: rescue a page from the balloon, if it is not empty. */ +@@ -156,6 +156,8 @@ static struct page *balloon_retrieve(void) + else + balloon_stats.balloon_low--; + ++ totalram_pages++; ++ + return page; + } + +@@ -181,7 +183,7 @@ static void balloon_alarm(unsigned long unused) + + static unsigned long current_target(void) + { +- unsigned long target = min(balloon_stats.target_pages, balloon_stats.hard_limit); ++ unsigned long target = balloon_stats.target_pages; + + target = min(target, + balloon_stats.current_pages + +@@ -217,23 +219,10 @@ static int increase_reservation(unsigned long nr_pages) + set_xen_guest_handle(reservation.extent_start, frame_list); + reservation.nr_extents = nr_pages; + rc = HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation); +- if (rc < nr_pages) { +- if (rc > 0) { +- int ret; +- +- /* We hit the Xen hard limit: reprobe. */ +- reservation.nr_extents = rc; +- ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, +- &reservation); +- BUG_ON(ret != rc); +- } +- if (rc >= 0) +- balloon_stats.hard_limit = (balloon_stats.current_pages + rc - +- balloon_stats.driver_pages); ++ if (rc < 0) + goto out; +- } + +- for (i = 0; i < nr_pages; i++) { ++ for (i = 0; i < rc; i++) { + page = balloon_retrieve(); + BUG_ON(page == NULL); + +@@ -259,13 +248,12 @@ static int increase_reservation(unsigned long nr_pages) + __free_page(page); + } + +- balloon_stats.current_pages += nr_pages; +- totalram_pages = balloon_stats.current_pages; ++ balloon_stats.current_pages += rc; + + out: + spin_unlock_irqrestore(&balloon_lock, flags); + +- return 0; ++ return rc < 0 ? rc : rc != nr_pages; + } + + static int decrease_reservation(unsigned long nr_pages) +@@ -323,7 +311,6 @@ static int decrease_reservation(unsigned long nr_pages) + BUG_ON(ret != nr_pages); + + balloon_stats.current_pages -= nr_pages; +- totalram_pages = balloon_stats.current_pages; + + spin_unlock_irqrestore(&balloon_lock, flags); + +@@ -367,7 +354,6 @@ static void balloon_process(struct work_struct *work) + static void balloon_set_new_target(unsigned long target) + { + /* No need for lock. Not read-modify-write updates. */ +- balloon_stats.hard_limit = ~0UL; + balloon_stats.target_pages = target; + schedule_work(&balloon_worker); + } +@@ -422,12 +408,10 @@ static int __init balloon_init(void) + pr_info("xen_balloon: Initialising balloon driver.\n"); + + balloon_stats.current_pages = min(xen_start_info->nr_pages, max_pfn); +- totalram_pages = balloon_stats.current_pages; + balloon_stats.target_pages = balloon_stats.current_pages; + balloon_stats.balloon_low = 0; + balloon_stats.balloon_high = 0; + balloon_stats.driver_pages = 0UL; +- balloon_stats.hard_limit = ~0UL; + + init_timer(&balloon_timer); + balloon_timer.data = 0; +@@ -472,9 +456,6 @@ module_exit(balloon_exit); + BALLOON_SHOW(current_kb, "%lu\n", PAGES2KB(balloon_stats.current_pages)); + BALLOON_SHOW(low_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_low)); + BALLOON_SHOW(high_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_high)); +-BALLOON_SHOW(hard_limit_kb, +- (balloon_stats.hard_limit!=~0UL) ? "%lu\n" : "???\n", +- (balloon_stats.hard_limit!=~0UL) ? PAGES2KB(balloon_stats.hard_limit) : 0); + BALLOON_SHOW(driver_kb, "%lu\n", PAGES2KB(balloon_stats.driver_pages)); + + static ssize_t show_target_kb(struct sys_device *dev, struct sysdev_attribute *attr, +@@ -544,7 +525,6 @@ static struct attribute *balloon_info_attrs[] = { + &attr_current_kb.attr, + &attr_low_kb.attr, + &attr_high_kb.attr, +- &attr_hard_limit_kb.attr, + &attr_driver_kb.attr, + NULL + }; +diff --git a/drivers/xen/events.c b/drivers/xen/events.c +index 2f57276..ce602dd 100644 +--- a/drivers/xen/events.c ++++ b/drivers/xen/events.c +@@ -474,6 +474,9 @@ static void unbind_from_irq(unsigned int irq) + bind_evtchn_to_cpu(evtchn, 0); + + evtchn_to_irq[evtchn] = -1; ++ } ++ ++ if (irq_info[irq].type != IRQT_UNBOUND) { + irq_info[irq] = mk_unbound_info(); + + dynamic_irq_cleanup(irq); +diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c +index 10d03d7..c499793 100644 +--- a/drivers/xen/manage.c ++++ b/drivers/xen/manage.c +@@ -43,7 +43,6 @@ static int xen_suspend(void *data) + if (err) { + printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n", + err); +- dpm_resume_noirq(PMSG_RESUME); + return err; + } + +@@ -69,7 +68,6 @@ static int xen_suspend(void *data) + } + + sysdev_resume(); +- dpm_resume_noirq(PMSG_RESUME); + + return 0; + } +@@ -81,6 +79,12 @@ static void do_suspend(void) + + shutting_down = SHUTDOWN_SUSPEND; + ++ err = stop_machine_create(); ++ if (err) { ++ printk(KERN_ERR "xen suspend: failed to setup stop_machine %d\n", err); ++ goto out; ++ } ++ + #ifdef CONFIG_PREEMPT + /* If the kernel is preemptible, we need to freeze all the processes + to prevent them from being in the middle of a pagetable update +@@ -88,29 +92,32 @@ static void do_suspend(void) + err = freeze_processes(); + if (err) { + printk(KERN_ERR "xen suspend: freeze failed %d\n", err); +- return; ++ goto out_destroy_sm; + } + #endif + + err = dpm_suspend_start(PMSG_SUSPEND); + if (err) { + printk(KERN_ERR "xen suspend: dpm_suspend_start %d\n", err); +- goto out; ++ goto out_thaw; + } + +- printk(KERN_DEBUG "suspending xenstore...\n"); +- xs_suspend(); +- + err = dpm_suspend_noirq(PMSG_SUSPEND); + if (err) { + printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err); +- goto resume_devices; ++ goto out_resume; + } + ++ printk(KERN_DEBUG "suspending xenstore...\n"); ++ xs_suspend(); ++ + err = stop_machine(xen_suspend, &cancelled, cpumask_of(0)); ++ ++ dpm_resume_noirq(PMSG_RESUME); ++ + if (err) { + printk(KERN_ERR "failed to start xen_suspend: %d\n", err); +- goto out; ++ cancelled = 1; + } + + if (!cancelled) { +@@ -119,17 +126,21 @@ static void do_suspend(void) + } else + xs_suspend_cancel(); + +- dpm_resume_noirq(PMSG_RESUME); +- +-resume_devices: ++out_resume: + dpm_resume_end(PMSG_RESUME); + + /* Make sure timer events get retriggered on all CPUs */ + clock_was_set(); +-out: ++ ++out_thaw: + #ifdef CONFIG_PREEMPT + thaw_processes(); ++ ++out_destroy_sm: + #endif ++ stop_machine_destroy(); ++ ++out: + shutting_down = SHUTDOWN_INVALID; + } + #endif /* CONFIG_PM_SLEEP */ +diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c +index d42e25d..3800da7 100644 +--- a/drivers/xen/xenbus/xenbus_probe.c ++++ b/drivers/xen/xenbus/xenbus_probe.c +@@ -454,21 +454,21 @@ static ssize_t xendev_show_nodename(struct device *dev, + { + return sprintf(buf, "%s\n", to_xenbus_device(dev)->nodename); + } +-DEVICE_ATTR(nodename, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_nodename, NULL); ++static DEVICE_ATTR(nodename, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_nodename, NULL); + + static ssize_t xendev_show_devtype(struct device *dev, + struct device_attribute *attr, char *buf) + { + return sprintf(buf, "%s\n", to_xenbus_device(dev)->devicetype); + } +-DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL); ++static DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL); + + static ssize_t xendev_show_modalias(struct device *dev, + struct device_attribute *attr, char *buf) + { + return sprintf(buf, "xen:%s\n", to_xenbus_device(dev)->devicetype); + } +-DEVICE_ATTR(modalias, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_modalias, NULL); ++static DEVICE_ATTR(modalias, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_modalias, NULL); + + int xenbus_probe_node(struct xen_bus_type *bus, + const char *type, +diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c +index d22438e..39c6ee8 100644 +--- a/fs/debugfs/inode.c ++++ b/fs/debugfs/inode.c +@@ -32,7 +32,9 @@ static struct vfsmount *debugfs_mount; + static int debugfs_mount_count; + static bool debugfs_registered; + +-static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t dev) ++static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t dev, ++ void *data, const struct file_operations *fops) ++ + { + struct inode *inode = new_inode(sb); + +@@ -44,14 +46,18 @@ static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t d + init_special_inode(inode, mode, dev); + break; + case S_IFREG: +- inode->i_fop = &debugfs_file_operations; ++ inode->i_fop = fops ? fops : &debugfs_file_operations; ++ inode->i_private = data; + break; + case S_IFLNK: + inode->i_op = &debugfs_link_operations; ++ inode->i_fop = fops; ++ inode->i_private = data; + break; + case S_IFDIR: + inode->i_op = &simple_dir_inode_operations; +- inode->i_fop = &simple_dir_operations; ++ inode->i_fop = fops ? fops : &simple_dir_operations; ++ inode->i_private = data; + + /* directory inodes start off with i_nlink == 2 + * (for "." entry) */ +@@ -64,7 +70,8 @@ static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t d + + /* SMP-safe */ + static int debugfs_mknod(struct inode *dir, struct dentry *dentry, +- int mode, dev_t dev) ++ int mode, dev_t dev, void *data, ++ const struct file_operations *fops) + { + struct inode *inode; + int error = -EPERM; +@@ -72,7 +79,7 @@ static int debugfs_mknod(struct inode *dir, struct dentry *dentry, + if (dentry->d_inode) + return -EEXIST; + +- inode = debugfs_get_inode(dir->i_sb, mode, dev); ++ inode = debugfs_get_inode(dir->i_sb, mode, dev, data, fops); + if (inode) { + d_instantiate(dentry, inode); + dget(dentry); +@@ -81,12 +88,13 @@ static int debugfs_mknod(struct inode *dir, struct dentry *dentry, + return error; + } + +-static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) ++static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode, ++ void *data, const struct file_operations *fops) + { + int res; + + mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR; +- res = debugfs_mknod(dir, dentry, mode, 0); ++ res = debugfs_mknod(dir, dentry, mode, 0, data, fops); + if (!res) { + inc_nlink(dir); + fsnotify_mkdir(dir, dentry); +@@ -94,18 +102,20 @@ static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) + return res; + } + +-static int debugfs_link(struct inode *dir, struct dentry *dentry, int mode) ++static int debugfs_link(struct inode *dir, struct dentry *dentry, int mode, ++ void *data, const struct file_operations *fops) + { + mode = (mode & S_IALLUGO) | S_IFLNK; +- return debugfs_mknod(dir, dentry, mode, 0); ++ return debugfs_mknod(dir, dentry, mode, 0, data, fops); + } + +-static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode) ++static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode, ++ void *data, const struct file_operations *fops) + { + int res; + + mode = (mode & S_IALLUGO) | S_IFREG; +- res = debugfs_mknod(dir, dentry, mode, 0); ++ res = debugfs_mknod(dir, dentry, mode, 0, data, fops); + if (!res) + fsnotify_create(dir, dentry); + return res; +@@ -139,7 +149,9 @@ static struct file_system_type debug_fs_type = { + + static int debugfs_create_by_name(const char *name, mode_t mode, + struct dentry *parent, +- struct dentry **dentry) ++ struct dentry **dentry, ++ void *data, ++ const struct file_operations *fops) + { + int error = 0; + +@@ -164,13 +176,16 @@ static int debugfs_create_by_name(const char *name, mode_t mode, + if (!IS_ERR(*dentry)) { + switch (mode & S_IFMT) { + case S_IFDIR: +- error = debugfs_mkdir(parent->d_inode, *dentry, mode); ++ error = debugfs_mkdir(parent->d_inode, *dentry, mode, ++ data, fops); + break; + case S_IFLNK: +- error = debugfs_link(parent->d_inode, *dentry, mode); ++ error = debugfs_link(parent->d_inode, *dentry, mode, ++ data, fops); + break; + default: +- error = debugfs_create(parent->d_inode, *dentry, mode); ++ error = debugfs_create(parent->d_inode, *dentry, mode, ++ data, fops); + break; + } + dput(*dentry); +@@ -221,19 +236,13 @@ struct dentry *debugfs_create_file(const char *name, mode_t mode, + if (error) + goto exit; + +- error = debugfs_create_by_name(name, mode, parent, &dentry); ++ error = debugfs_create_by_name(name, mode, parent, &dentry, ++ data, fops); + if (error) { + dentry = NULL; + simple_release_fs(&debugfs_mount, &debugfs_mount_count); + goto exit; + } +- +- if (dentry->d_inode) { +- if (data) +- dentry->d_inode->i_private = data; +- if (fops) +- dentry->d_inode->i_fop = fops; +- } + exit: + return dentry; + } +diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c +index d5f8c96..8882ecc 100644 +--- a/fs/devpts/inode.c ++++ b/fs/devpts/inode.c +@@ -517,11 +517,23 @@ int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty) + + struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number) + { ++ struct dentry *dentry; ++ struct tty_struct *tty; ++ + BUG_ON(pts_inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR)); + ++ /* Ensure dentry has not been deleted by devpts_pty_kill() */ ++ dentry = d_find_alias(pts_inode); ++ if (!dentry) ++ return NULL; ++ ++ tty = NULL; + if (pts_inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC) +- return (struct tty_struct *)pts_inode->i_private; +- return NULL; ++ tty = (struct tty_struct *)pts_inode->i_private; ++ ++ dput(dentry); ++ ++ return tty; + } + + void devpts_pty_kill(struct tty_struct *tty) +diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c +index 354ed3b..f9d6937 100644 +--- a/fs/ext3/inode.c ++++ b/fs/ext3/inode.c +@@ -1151,6 +1151,16 @@ static int do_journal_get_write_access(handle_t *handle, + return ext3_journal_get_write_access(handle, bh); + } + ++/* ++ * Truncate blocks that were not used by write. We have to truncate the ++ * pagecache as well so that corresponding buffers get properly unmapped. ++ */ ++static void ext3_truncate_failed_write(struct inode *inode) ++{ ++ truncate_inode_pages(inode->i_mapping, inode->i_size); ++ ext3_truncate(inode); ++} ++ + static int ext3_write_begin(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, unsigned flags, + struct page **pagep, void **fsdata) +@@ -1209,7 +1219,7 @@ write_begin_failed: + unlock_page(page); + page_cache_release(page); + if (pos + len > inode->i_size) +- ext3_truncate(inode); ++ ext3_truncate_failed_write(inode); + } + if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) + goto retry; +@@ -1304,7 +1314,7 @@ static int ext3_ordered_write_end(struct file *file, + page_cache_release(page); + + if (pos + len > inode->i_size) +- ext3_truncate(inode); ++ ext3_truncate_failed_write(inode); + return ret ? ret : copied; + } + +@@ -1330,7 +1340,7 @@ static int ext3_writeback_write_end(struct file *file, + page_cache_release(page); + + if (pos + len > inode->i_size) +- ext3_truncate(inode); ++ ext3_truncate_failed_write(inode); + return ret ? ret : copied; + } + +@@ -1383,7 +1393,7 @@ static int ext3_journalled_write_end(struct file *file, + page_cache_release(page); + + if (pos + len > inode->i_size) +- ext3_truncate(inode); ++ ext3_truncate_failed_write(inode); + return ret ? ret : copied; + } + +diff --git a/fs/hfs/catalog.c b/fs/hfs/catalog.c +index 6d98f11..424b033 100644 +--- a/fs/hfs/catalog.c ++++ b/fs/hfs/catalog.c +@@ -289,6 +289,10 @@ int hfs_cat_move(u32 cnid, struct inode *src_dir, struct qstr *src_name, + err = hfs_brec_find(&src_fd); + if (err) + goto out; ++ if (src_fd.entrylength > sizeof(entry) || src_fd.entrylength < 0) { ++ err = -EIO; ++ goto out; ++ } + + hfs_bnode_read(src_fd.bnode, &entry, src_fd.entryoffset, + src_fd.entrylength); +diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c +index 7c69b98..2b3b861 100644 +--- a/fs/hfs/dir.c ++++ b/fs/hfs/dir.c +@@ -79,6 +79,11 @@ static int hfs_readdir(struct file *filp, void *dirent, filldir_t filldir) + filp->f_pos++; + /* fall through */ + case 1: ++ if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) { ++ err = -EIO; ++ goto out; ++ } ++ + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); + if (entry.type != HFS_CDR_THD) { + printk(KERN_ERR "hfs: bad catalog folder thread\n"); +@@ -109,6 +114,12 @@ static int hfs_readdir(struct file *filp, void *dirent, filldir_t filldir) + err = -EIO; + goto out; + } ++ ++ if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) { ++ err = -EIO; ++ goto out; ++ } ++ + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); + type = entry.type; + len = hfs_mac2asc(sb, strbuf, &fd.key->cat.CName); +diff --git a/fs/hfs/super.c b/fs/hfs/super.c +index f7fcbe4..5ed7252 100644 +--- a/fs/hfs/super.c ++++ b/fs/hfs/super.c +@@ -409,8 +409,13 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent) + /* try to get the root inode */ + hfs_find_init(HFS_SB(sb)->cat_tree, &fd); + res = hfs_cat_find_brec(sb, HFS_ROOT_CNID, &fd); +- if (!res) ++ if (!res) { ++ if (fd.entrylength > sizeof(rec) || fd.entrylength < 0) { ++ res = -EIO; ++ goto bail; ++ } + hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, fd.entrylength); ++ } + if (res) { + hfs_find_exit(&fd); + goto bail_no_root; +diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c +index 82c295d..b7ca3a9 100644 +--- a/fs/jbd2/journal.c ++++ b/fs/jbd2/journal.c +@@ -1253,6 +1253,13 @@ int jbd2_journal_load(journal_t *journal) + if (jbd2_journal_recover(journal)) + goto recovery_error; + ++ if (journal->j_failed_commit) { ++ printk(KERN_ERR "JBD2: journal transaction %u on %s " ++ "is corrupt.\n", journal->j_failed_commit, ++ journal->j_devname); ++ return -EIO; ++ } ++ + /* OK, we've finished with the dynamic journal bits: + * reinitialise the dynamic contents of the superblock in memory + * and reset them on disk. */ +diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c +index 090c556..3b6f2fa 100644 +--- a/fs/jffs2/gc.c ++++ b/fs/jffs2/gc.c +@@ -700,7 +700,8 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_ + struct jffs2_raw_inode ri; + struct jffs2_node_frag *last_frag; + union jffs2_device_node dev; +- char *mdata = NULL, mdatalen = 0; ++ char *mdata = NULL; ++ int mdatalen = 0; + uint32_t alloclen, ilen; + int ret; + +diff --git a/fs/nfs/write.c b/fs/nfs/write.c +index 53eb26c..6fc3776 100644 +--- a/fs/nfs/write.c ++++ b/fs/nfs/write.c +@@ -1612,15 +1612,16 @@ int nfs_migrate_page(struct address_space *mapping, struct page *newpage, + if (ret) + goto out_unlock; + page_cache_get(newpage); ++ spin_lock(&mapping->host->i_lock); + req->wb_page = newpage; + SetPagePrivate(newpage); +- set_page_private(newpage, page_private(page)); ++ set_page_private(newpage, (unsigned long)req); + ClearPagePrivate(page); + set_page_private(page, 0); ++ spin_unlock(&mapping->host->i_lock); + page_cache_release(page); + out_unlock: + nfs_clear_page_tag_locked(req); +- nfs_release_request(req); + out: + return ret; + } +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index c8e64bb..9d3d684 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -1295,6 +1295,7 @@ extern u32 drm_vblank_count(struct drm_device *dev, int crtc); + extern void drm_handle_vblank(struct drm_device *dev, int crtc); + extern int drm_vblank_get(struct drm_device *dev, int crtc); + extern void drm_vblank_put(struct drm_device *dev, int crtc); ++extern void drm_vblank_off(struct drm_device *dev, int crtc); + extern void drm_vblank_cleanup(struct drm_device *dev); + /* Modesetting support */ + extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc); +diff --git a/include/drm/ttm/ttm_memory.h b/include/drm/ttm/ttm_memory.h +index 6983a7c..b199170 100644 +--- a/include/drm/ttm/ttm_memory.h ++++ b/include/drm/ttm/ttm_memory.h +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + + /** + * struct ttm_mem_shrink - callback to shrink TTM memory usage. +diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h +index ff037f0..9bace4b 100644 +--- a/include/linux/hrtimer.h ++++ b/include/linux/hrtimer.h +@@ -446,7 +446,7 @@ extern void timer_stats_update_stats(void *timer, pid_t pid, void *startf, + + static inline void timer_stats_account_hrtimer(struct hrtimer *timer) + { +- if (likely(!timer->start_site)) ++ if (likely(!timer_stats_active)) + return; + timer_stats_update_stats(timer, timer->start_pid, timer->start_site, + timer->function, timer->start_comm, 0); +@@ -457,8 +457,6 @@ extern void __timer_stats_hrtimer_set_start_info(struct hrtimer *timer, + + static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer) + { +- if (likely(!timer_stats_active)) +- return; + __timer_stats_hrtimer_set_start_info(timer, __builtin_return_address(0)); + } + +diff --git a/include/linux/kvm.h b/include/linux/kvm.h +index f8f8900..8908dd6 100644 +--- a/include/linux/kvm.h ++++ b/include/linux/kvm.h +@@ -116,6 +116,11 @@ struct kvm_run { + __u64 cr8; + __u64 apic_base; + ++#ifdef __KVM_S390 ++ /* the processor status word for s390 */ ++ __u64 psw_mask; /* psw upper half */ ++ __u64 psw_addr; /* psw lower half */ ++#endif + union { + /* KVM_EXIT_UNKNOWN */ + struct { +@@ -167,8 +172,6 @@ struct kvm_run { + /* KVM_EXIT_S390_SIEIC */ + struct { + __u8 icptcode; +- __u64 mask; /* psw upper half */ +- __u64 addr; /* psw lower half */ + __u16 ipa; + __u32 ipb; + } s390_sieic; +@@ -474,6 +477,7 @@ struct kvm_irq_routing { + }; + + #endif ++#define KVM_CAP_S390_PSW 42 + + #ifdef KVM_CAP_MCE + /* x86 MCE */ +diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h +index 9e70126..81c9689 100644 +--- a/include/linux/perf_event.h ++++ b/include/linux/perf_event.h +@@ -219,7 +219,7 @@ struct perf_event_attr { + #define PERF_EVENT_IOC_DISABLE _IO ('$', 1) + #define PERF_EVENT_IOC_REFRESH _IO ('$', 2) + #define PERF_EVENT_IOC_RESET _IO ('$', 3) +-#define PERF_EVENT_IOC_PERIOD _IOW('$', 4, u64) ++#define PERF_EVENT_IOC_PERIOD _IOW('$', 4, __u64) + #define PERF_EVENT_IOC_SET_OUTPUT _IO ('$', 5) + + enum perf_event_ioc_flags { +diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h +index 3d15fb9..a4b947e 100644 +--- a/include/linux/usb_usual.h ++++ b/include/linux/usb_usual.h +@@ -56,7 +56,9 @@ + US_FLAG(SANE_SENSE, 0x00008000) \ + /* Sane Sense (> 18 bytes) */ \ + US_FLAG(CAPACITY_OK, 0x00010000) \ +- /* READ CAPACITY response is correct */ ++ /* READ CAPACITY response is correct */ \ ++ US_FLAG(BAD_SENSE, 0x00020000) \ ++ /* Bad Sense (never more than 18 bytes) */ + + #define US_FLAG(name, value) US_FL_##name = value , + enum { US_DO_ALL_FLAGS }; +diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h +index 227c2a5..3c123c3 100644 +--- a/include/linux/vmalloc.h ++++ b/include/linux/vmalloc.h +@@ -115,9 +115,11 @@ extern rwlock_t vmlist_lock; + extern struct vm_struct *vmlist; + extern __init void vm_area_register_early(struct vm_struct *vm, size_t align); + ++#ifndef CONFIG_HAVE_LEGACY_PER_CPU_AREA + struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets, + const size_t *sizes, int nr_vms, + size_t align, gfp_t gfp_mask); ++#endif + + void pcpu_free_vm_areas(struct vm_struct **vms, int nr_vms); + +diff --git a/include/net/tcp.h b/include/net/tcp.h +index 03a49c7..842ac4d 100644 +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -1263,14 +1263,20 @@ static inline struct sk_buff *tcp_write_queue_prev(struct sock *sk, struct sk_bu + * TCP connection after "boundary" unsucessful, exponentially backed-off + * retransmissions with an initial RTO of TCP_RTO_MIN. + */ +-static inline bool retransmits_timed_out(const struct sock *sk, ++static inline bool retransmits_timed_out(struct sock *sk, + unsigned int boundary) + { + unsigned int timeout, linear_backoff_thresh; ++ unsigned int start_ts; + + if (!inet_csk(sk)->icsk_retransmits) + return false; + ++ if (unlikely(!tcp_sk(sk)->retrans_stamp)) ++ start_ts = TCP_SKB_CB(tcp_write_queue_head(sk))->when; ++ else ++ start_ts = tcp_sk(sk)->retrans_stamp; ++ + linear_backoff_thresh = ilog2(TCP_RTO_MAX/TCP_RTO_MIN); + + if (boundary <= linear_backoff_thresh) +@@ -1279,7 +1285,7 @@ static inline bool retransmits_timed_out(const struct sock *sk, + timeout = ((2 << linear_backoff_thresh) - 1) * TCP_RTO_MIN + + (boundary - linear_backoff_thresh) * TCP_RTO_MAX; + +- return (tcp_time_stamp - tcp_sk(sk)->retrans_stamp) >= timeout; ++ return (tcp_time_stamp - start_ts) >= timeout; + } + + static inline struct sk_buff *tcp_send_head(struct sock *sk) +diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h +index cc0d966..dacb8ef 100644 +--- a/include/trace/ftrace.h ++++ b/include/trace/ftrace.h +@@ -159,7 +159,7 @@ + #undef __get_str + + #undef TP_printk +-#define TP_printk(fmt, args...) "%s, %s\n", #fmt, __stringify(args) ++#define TP_printk(fmt, args...) "\"%s\", %s\n", fmt, __stringify(args) + + #undef TP_fast_assign + #define TP_fast_assign(args...) args +diff --git a/kernel/acct.c b/kernel/acct.c +index 9a4715a..a6605ca 100644 +--- a/kernel/acct.c ++++ b/kernel/acct.c +@@ -536,7 +536,8 @@ static void do_acct_process(struct bsd_acct_struct *acct, + do_div(elapsed, AHZ); + ac.ac_btime = get_seconds() - elapsed; + /* we really need to bite the bullet and change layout */ +- current_uid_gid(&ac.ac_uid, &ac.ac_gid); ++ ac.ac_uid = orig_cred->uid; ++ ac.ac_gid = orig_cred->gid; + #if ACCT_VERSION==2 + ac.ac_ahz = AHZ; + #endif +diff --git a/kernel/futex.c b/kernel/futex.c +index fb65e82..d73ef1f 100644 +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -304,8 +304,14 @@ void put_futex_key(int fshared, union futex_key *key) + */ + static int fault_in_user_writeable(u32 __user *uaddr) + { +- int ret = get_user_pages(current, current->mm, (unsigned long)uaddr, +- 1, 1, 0, NULL, NULL); ++ struct mm_struct *mm = current->mm; ++ int ret; ++ ++ down_read(&mm->mmap_sem); ++ ret = get_user_pages(current, mm, (unsigned long)uaddr, ++ 1, 1, 0, NULL, NULL); ++ up_read(&mm->mmap_sem); ++ + return ret < 0 ? ret : 0; + } + +diff --git a/kernel/perf_event.c b/kernel/perf_event.c +index 7f29643..6eee915 100644 +--- a/kernel/perf_event.c ++++ b/kernel/perf_event.c +@@ -1583,7 +1583,7 @@ static struct perf_event_context *find_get_context(pid_t pid, int cpu) + if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN)) + return ERR_PTR(-EACCES); + +- if (cpu < 0 || cpu > num_possible_cpus()) ++ if (cpu < 0 || cpu >= nr_cpumask_bits) + return ERR_PTR(-EINVAL); + + /* +@@ -2174,6 +2174,7 @@ static void perf_mmap_data_free(struct perf_mmap_data *data) + perf_mmap_free_page((unsigned long)data->user_page); + for (i = 0; i < data->nr_pages; i++) + perf_mmap_free_page((unsigned long)data->data_pages[i]); ++ kfree(data); + } + + #else +@@ -2214,6 +2215,7 @@ static void perf_mmap_data_free_work(struct work_struct *work) + perf_mmap_unmark_page(base + (i * PAGE_SIZE)); + + vfree(base); ++ kfree(data); + } + + static void perf_mmap_data_free(struct perf_mmap_data *data) +@@ -2319,7 +2321,6 @@ static void perf_mmap_data_free_rcu(struct rcu_head *rcu_head) + + data = container_of(rcu_head, struct perf_mmap_data, rcu_head); + perf_mmap_data_free(data); +- kfree(data); + } + + static void perf_mmap_data_release(struct perf_event *event) +@@ -3949,6 +3950,7 @@ static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer) + event->pmu->read(event); + + data.addr = 0; ++ data.period = event->hw.last_period; + regs = get_irq_regs(); + /* + * In case we exclude kernel IPs or are somehow not in interrupt +diff --git a/kernel/rcutree.c b/kernel/rcutree.c +index f3077c0..683c4f3 100644 +--- a/kernel/rcutree.c ++++ b/kernel/rcutree.c +@@ -176,9 +176,29 @@ static struct rcu_node *rcu_get_root(struct rcu_state *rsp) + return &rsp->node[0]; + } + ++/* ++ * Record the specified "completed" value, which is later used to validate ++ * dynticks counter manipulations and CPU-offline checks. Specify ++ * "rsp->completed - 1" to unconditionally invalidate any future dynticks ++ * manipulations and CPU-offline checks. Such invalidation is useful at ++ * the beginning of a grace period. ++ */ ++static void dyntick_record_completed(struct rcu_state *rsp, long comp) ++{ ++ rsp->dynticks_completed = comp; ++} ++ + #ifdef CONFIG_SMP + + /* ++ * Recall the previously recorded value of the completion for dynticks. ++ */ ++static long dyntick_recall_completed(struct rcu_state *rsp) ++{ ++ return rsp->dynticks_completed; ++} ++ ++/* + * If the specified CPU is offline, tell the caller that it is in + * a quiescent state. Otherwise, whack it with a reschedule IPI. + * Grace periods can end up waiting on an offline CPU when that +@@ -335,28 +355,9 @@ void rcu_irq_exit(void) + set_need_resched(); + } + +-/* +- * Record the specified "completed" value, which is later used to validate +- * dynticks counter manipulations. Specify "rsp->completed - 1" to +- * unconditionally invalidate any future dynticks manipulations (which is +- * useful at the beginning of a grace period). +- */ +-static void dyntick_record_completed(struct rcu_state *rsp, long comp) +-{ +- rsp->dynticks_completed = comp; +-} +- + #ifdef CONFIG_SMP + + /* +- * Recall the previously recorded value of the completion for dynticks. +- */ +-static long dyntick_recall_completed(struct rcu_state *rsp) +-{ +- return rsp->dynticks_completed; +-} +- +-/* + * Snapshot the specified CPU's dynticks counter so that we can later + * credit them with an implicit quiescent state. Return 1 if this CPU + * is in dynticks idle mode, which is an extended quiescent state. +@@ -419,24 +420,8 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp) + + #else /* #ifdef CONFIG_NO_HZ */ + +-static void dyntick_record_completed(struct rcu_state *rsp, long comp) +-{ +-} +- + #ifdef CONFIG_SMP + +-/* +- * If there are no dynticks, then the only way that a CPU can passively +- * be in a quiescent state is to be offline. Unlike dynticks idle, which +- * is a point in time during the prior (already finished) grace period, +- * an offline CPU is always in a quiescent state, and thus can be +- * unconditionally applied. So just return the current value of completed. +- */ +-static long dyntick_recall_completed(struct rcu_state *rsp) +-{ +- return rsp->completed; +-} +- + static int dyntick_save_progress_counter(struct rcu_data *rdp) + { + return 0; +@@ -553,13 +538,33 @@ static void check_cpu_stall(struct rcu_state *rsp, struct rcu_data *rdp) + /* + * Update CPU-local rcu_data state to record the newly noticed grace period. + * This is used both when we started the grace period and when we notice +- * that someone else started the grace period. ++ * that someone else started the grace period. The caller must hold the ++ * ->lock of the leaf rcu_node structure corresponding to the current CPU, ++ * and must have irqs disabled. + */ ++static void __note_new_gpnum(struct rcu_state *rsp, struct rcu_node *rnp, struct rcu_data *rdp) ++{ ++ if (rdp->gpnum != rnp->gpnum) { ++ rdp->qs_pending = 1; ++ rdp->passed_quiesc = 0; ++ rdp->gpnum = rnp->gpnum; ++ } ++} ++ + static void note_new_gpnum(struct rcu_state *rsp, struct rcu_data *rdp) + { +- rdp->qs_pending = 1; +- rdp->passed_quiesc = 0; +- rdp->gpnum = rsp->gpnum; ++ unsigned long flags; ++ struct rcu_node *rnp; ++ ++ local_irq_save(flags); ++ rnp = rdp->mynode; ++ if (rdp->gpnum == ACCESS_ONCE(rnp->gpnum) || /* outside lock. */ ++ !spin_trylock(&rnp->lock)) { /* irqs already off, retry later. */ ++ local_irq_restore(flags); ++ return; ++ } ++ __note_new_gpnum(rsp, rnp, rdp); ++ spin_unlock_irqrestore(&rnp->lock, flags); + } + + /* +@@ -583,6 +588,79 @@ check_for_new_grace_period(struct rcu_state *rsp, struct rcu_data *rdp) + } + + /* ++ * Advance this CPU's callbacks, but only if the current grace period ++ * has ended. This may be called only from the CPU to whom the rdp ++ * belongs. In addition, the corresponding leaf rcu_node structure's ++ * ->lock must be held by the caller, with irqs disabled. ++ */ ++static void ++__rcu_process_gp_end(struct rcu_state *rsp, struct rcu_node *rnp, struct rcu_data *rdp) ++{ ++ /* Did another grace period end? */ ++ if (rdp->completed != rnp->completed) { ++ ++ /* Advance callbacks. No harm if list empty. */ ++ rdp->nxttail[RCU_DONE_TAIL] = rdp->nxttail[RCU_WAIT_TAIL]; ++ rdp->nxttail[RCU_WAIT_TAIL] = rdp->nxttail[RCU_NEXT_READY_TAIL]; ++ rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL]; ++ ++ /* Remember that we saw this grace-period completion. */ ++ rdp->completed = rnp->completed; ++ } ++} ++ ++/* ++ * Advance this CPU's callbacks, but only if the current grace period ++ * has ended. This may be called only from the CPU to whom the rdp ++ * belongs. ++ */ ++static void ++rcu_process_gp_end(struct rcu_state *rsp, struct rcu_data *rdp) ++{ ++ unsigned long flags; ++ struct rcu_node *rnp; ++ ++ local_irq_save(flags); ++ rnp = rdp->mynode; ++ if (rdp->completed == ACCESS_ONCE(rnp->completed) || /* outside lock. */ ++ !spin_trylock(&rnp->lock)) { /* irqs already off, retry later. */ ++ local_irq_restore(flags); ++ return; ++ } ++ __rcu_process_gp_end(rsp, rnp, rdp); ++ spin_unlock_irqrestore(&rnp->lock, flags); ++} ++ ++/* ++ * Do per-CPU grace-period initialization for running CPU. The caller ++ * must hold the lock of the leaf rcu_node structure corresponding to ++ * this CPU. ++ */ ++static void ++rcu_start_gp_per_cpu(struct rcu_state *rsp, struct rcu_node *rnp, struct rcu_data *rdp) ++{ ++ /* Prior grace period ended, so advance callbacks for current CPU. */ ++ __rcu_process_gp_end(rsp, rnp, rdp); ++ ++ /* ++ * Because this CPU just now started the new grace period, we know ++ * that all of its callbacks will be covered by this upcoming grace ++ * period, even the ones that were registered arbitrarily recently. ++ * Therefore, advance all outstanding callbacks to RCU_WAIT_TAIL. ++ * ++ * Other CPUs cannot be sure exactly when the grace period started. ++ * Therefore, their recently registered callbacks must pass through ++ * an additional RCU_NEXT_READY stage, so that they will be handled ++ * by the next RCU grace period. ++ */ ++ rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL]; ++ rdp->nxttail[RCU_WAIT_TAIL] = rdp->nxttail[RCU_NEXT_TAIL]; ++ ++ /* Set state so that this CPU will detect the next quiescent state. */ ++ __note_new_gpnum(rsp, rnp, rdp); ++} ++ ++/* + * Start a new RCU grace period if warranted, re-initializing the hierarchy + * in preparation for detecting the next grace period. The caller must hold + * the root node's ->lock, which is released before return. Hard irqs must +@@ -607,28 +685,15 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags) + rsp->jiffies_force_qs = jiffies + RCU_JIFFIES_TILL_FORCE_QS; + record_gp_stall_check_time(rsp); + dyntick_record_completed(rsp, rsp->completed - 1); +- note_new_gpnum(rsp, rdp); +- +- /* +- * Because this CPU just now started the new grace period, we know +- * that all of its callbacks will be covered by this upcoming grace +- * period, even the ones that were registered arbitrarily recently. +- * Therefore, advance all outstanding callbacks to RCU_WAIT_TAIL. +- * +- * Other CPUs cannot be sure exactly when the grace period started. +- * Therefore, their recently registered callbacks must pass through +- * an additional RCU_NEXT_READY stage, so that they will be handled +- * by the next RCU grace period. +- */ +- rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL]; +- rdp->nxttail[RCU_WAIT_TAIL] = rdp->nxttail[RCU_NEXT_TAIL]; + + /* Special-case the common single-level case. */ + if (NUM_RCU_NODES == 1) { + rcu_preempt_check_blocked_tasks(rnp); + rnp->qsmask = rnp->qsmaskinit; + rnp->gpnum = rsp->gpnum; ++ rnp->completed = rsp->completed; + rsp->signaled = RCU_SIGNAL_INIT; /* force_quiescent_state OK. */ ++ rcu_start_gp_per_cpu(rsp, rnp, rdp); + spin_unlock_irqrestore(&rnp->lock, flags); + return; + } +@@ -661,6 +726,9 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags) + rcu_preempt_check_blocked_tasks(rnp); + rnp->qsmask = rnp->qsmaskinit; + rnp->gpnum = rsp->gpnum; ++ rnp->completed = rsp->completed; ++ if (rnp == rdp->mynode) ++ rcu_start_gp_per_cpu(rsp, rnp, rdp); + spin_unlock(&rnp->lock); /* irqs remain disabled. */ + } + +@@ -672,34 +740,6 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags) + } + + /* +- * Advance this CPU's callbacks, but only if the current grace period +- * has ended. This may be called only from the CPU to whom the rdp +- * belongs. +- */ +-static void +-rcu_process_gp_end(struct rcu_state *rsp, struct rcu_data *rdp) +-{ +- long completed_snap; +- unsigned long flags; +- +- local_irq_save(flags); +- completed_snap = ACCESS_ONCE(rsp->completed); /* outside of lock. */ +- +- /* Did another grace period end? */ +- if (rdp->completed != completed_snap) { +- +- /* Advance callbacks. No harm if list empty. */ +- rdp->nxttail[RCU_DONE_TAIL] = rdp->nxttail[RCU_WAIT_TAIL]; +- rdp->nxttail[RCU_WAIT_TAIL] = rdp->nxttail[RCU_NEXT_READY_TAIL]; +- rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL]; +- +- /* Remember that we saw this grace-period completion. */ +- rdp->completed = completed_snap; +- } +- local_irq_restore(flags); +-} +- +-/* + * Clean up after the prior grace period and let rcu_start_gp() start up + * the next grace period if one is needed. Note that the caller must + * hold rnp->lock, as required by rcu_start_gp(), which will release it. +@@ -710,7 +750,6 @@ static void cpu_quiet_msk_finish(struct rcu_state *rsp, unsigned long flags) + WARN_ON_ONCE(!rcu_gp_in_progress(rsp)); + rsp->completed = rsp->gpnum; + rsp->signaled = RCU_GP_IDLE; +- rcu_process_gp_end(rsp, rsp->rda[smp_processor_id()]); + rcu_start_gp(rsp, flags); /* releases root node's rnp->lock. */ + } + +@@ -1144,6 +1183,7 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed) + long lastcomp; + struct rcu_node *rnp = rcu_get_root(rsp); + u8 signaled; ++ u8 forcenow; + + if (!rcu_gp_in_progress(rsp)) + return; /* No grace period in progress, nothing to force. */ +@@ -1180,16 +1220,23 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed) + if (rcu_process_dyntick(rsp, lastcomp, + dyntick_save_progress_counter)) + goto unlock_ret; ++ /* fall into next case. */ ++ ++ case RCU_SAVE_COMPLETED: + + /* Update state, record completion counter. */ ++ forcenow = 0; + spin_lock(&rnp->lock); + if (lastcomp == rsp->completed && +- rsp->signaled == RCU_SAVE_DYNTICK) { ++ rsp->signaled == signaled) { + rsp->signaled = RCU_FORCE_QS; + dyntick_record_completed(rsp, lastcomp); ++ forcenow = signaled == RCU_SAVE_COMPLETED; + } + spin_unlock(&rnp->lock); +- break; ++ if (!forcenow) ++ break; ++ /* fall into next case. */ + + case RCU_FORCE_QS: + +@@ -1544,21 +1591,16 @@ static void __cpuinit + rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptable) + { + unsigned long flags; +- long lastcomp; + unsigned long mask; + struct rcu_data *rdp = rsp->rda[cpu]; + struct rcu_node *rnp = rcu_get_root(rsp); + + /* Set up local state, ensuring consistent view of global state. */ + spin_lock_irqsave(&rnp->lock, flags); +- lastcomp = rsp->completed; +- rdp->completed = lastcomp; +- rdp->gpnum = lastcomp; + rdp->passed_quiesc = 0; /* We could be racing with new GP, */ + rdp->qs_pending = 1; /* so set up to respond to current GP. */ + rdp->beenonline = 1; /* We have now been online. */ + rdp->preemptable = preemptable; +- rdp->passed_quiesc_completed = lastcomp - 1; + rdp->qlen_last_fqs_check = 0; + rdp->n_force_qs_snap = rsp->n_force_qs; + rdp->blimit = blimit; +@@ -1580,6 +1622,11 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptable) + spin_lock(&rnp->lock); /* irqs already disabled. */ + rnp->qsmaskinit |= mask; + mask = rnp->grpmask; ++ if (rnp == rdp->mynode) { ++ rdp->gpnum = rnp->completed; /* if GP in progress... */ ++ rdp->completed = rnp->completed; ++ rdp->passed_quiesc_completed = rnp->completed - 1; ++ } + spin_unlock(&rnp->lock); /* irqs already disabled. */ + rnp = rnp->parent; + } while (rnp != NULL && !(rnp->qsmaskinit & mask)); +diff --git a/kernel/rcutree.h b/kernel/rcutree.h +index 1899023..ddb79ec 100644 +--- a/kernel/rcutree.h ++++ b/kernel/rcutree.h +@@ -84,6 +84,9 @@ struct rcu_node { + long gpnum; /* Current grace period for this node. */ + /* This will either be equal to or one */ + /* behind the root rcu_node's gpnum. */ ++ long completed; /* Last grace period completed for this node. */ ++ /* This will either be equal to or one */ ++ /* behind the root rcu_node's gpnum. */ + unsigned long qsmask; /* CPUs or groups that need to switch in */ + /* order for current grace period to proceed.*/ + /* In leaf rcu_node, each bit corresponds to */ +@@ -204,11 +207,12 @@ struct rcu_data { + #define RCU_GP_IDLE 0 /* No grace period in progress. */ + #define RCU_GP_INIT 1 /* Grace period being initialized. */ + #define RCU_SAVE_DYNTICK 2 /* Need to scan dyntick state. */ +-#define RCU_FORCE_QS 3 /* Need to force quiescent state. */ ++#define RCU_SAVE_COMPLETED 3 /* Need to save rsp->completed. */ ++#define RCU_FORCE_QS 4 /* Need to force quiescent state. */ + #ifdef CONFIG_NO_HZ + #define RCU_SIGNAL_INIT RCU_SAVE_DYNTICK + #else /* #ifdef CONFIG_NO_HZ */ +-#define RCU_SIGNAL_INIT RCU_FORCE_QS ++#define RCU_SIGNAL_INIT RCU_SAVE_COMPLETED + #endif /* #else #ifdef CONFIG_NO_HZ */ + + #define RCU_JIFFIES_TILL_FORCE_QS 3 /* for rsp->jiffies_force_qs */ +@@ -274,9 +278,8 @@ struct rcu_state { + unsigned long jiffies_stall; /* Time at which to check */ + /* for CPU stalls. */ + #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */ +-#ifdef CONFIG_NO_HZ + long dynticks_completed; /* Value of completed @ snap. */ +-#endif /* #ifdef CONFIG_NO_HZ */ ++ /* Protected by fqslock. */ + }; + + #ifdef RCU_TREE_NONCORE +@@ -298,7 +301,7 @@ DECLARE_PER_CPU(struct rcu_data, rcu_preempt_data); + #else /* #ifdef RCU_TREE_NONCORE */ + + /* Forward declarations for rcutree_plugin.h */ +-static inline void rcu_bootup_announce(void); ++static void rcu_bootup_announce(void); + long rcu_batches_completed(void); + static void rcu_preempt_note_context_switch(int cpu); + static int rcu_preempted_readers(struct rcu_node *rnp); +diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h +index ef2a58c..c03edf7 100644 +--- a/kernel/rcutree_plugin.h ++++ b/kernel/rcutree_plugin.h +@@ -33,7 +33,7 @@ DEFINE_PER_CPU(struct rcu_data, rcu_preempt_data); + /* + * Tell them what RCU they are running. + */ +-static inline void rcu_bootup_announce(void) ++static void rcu_bootup_announce(void) + { + printk(KERN_INFO + "Experimental preemptable hierarchical RCU implementation.\n"); +@@ -481,7 +481,7 @@ void exit_rcu(void) + /* + * Tell them what RCU they are running. + */ +-static inline void rcu_bootup_announce(void) ++static void rcu_bootup_announce(void) + { + printk(KERN_INFO "Hierarchical RCU implementation.\n"); + } +diff --git a/kernel/sched.c b/kernel/sched.c +index 3c11ae0..d079a9f 100644 +--- a/kernel/sched.c ++++ b/kernel/sched.c +@@ -591,6 +591,8 @@ struct rq { + + u64 rt_avg; + u64 age_stamp; ++ u64 idle_stamp; ++ u64 avg_idle; + #endif + + /* calc_load related fields */ +@@ -2440,6 +2442,17 @@ out_running: + #ifdef CONFIG_SMP + if (p->sched_class->task_wake_up) + p->sched_class->task_wake_up(rq, p); ++ ++ if (unlikely(rq->idle_stamp)) { ++ u64 delta = rq->clock - rq->idle_stamp; ++ u64 max = 2*sysctl_sched_migration_cost; ++ ++ if (delta > max) ++ rq->avg_idle = max; ++ else ++ update_avg(&rq->avg_idle, delta); ++ rq->idle_stamp = 0; ++ } + #endif + out: + task_rq_unlock(rq, &flags); +@@ -4126,7 +4139,7 @@ static int load_balance(int this_cpu, struct rq *this_rq, + unsigned long flags; + struct cpumask *cpus = __get_cpu_var(load_balance_tmpmask); + +- cpumask_setall(cpus); ++ cpumask_copy(cpus, cpu_online_mask); + + /* + * When power savings policy is enabled for the parent domain, idle +@@ -4289,7 +4302,7 @@ load_balance_newidle(int this_cpu, struct rq *this_rq, struct sched_domain *sd) + int all_pinned = 0; + struct cpumask *cpus = __get_cpu_var(load_balance_tmpmask); + +- cpumask_setall(cpus); ++ cpumask_copy(cpus, cpu_online_mask); + + /* + * When power savings policy is enabled for the parent domain, idle +@@ -4429,6 +4442,11 @@ static void idle_balance(int this_cpu, struct rq *this_rq) + int pulled_task = 0; + unsigned long next_balance = jiffies + HZ; + ++ this_rq->idle_stamp = this_rq->clock; ++ ++ if (this_rq->avg_idle < sysctl_sched_migration_cost) ++ return; ++ + for_each_domain(this_cpu, sd) { + unsigned long interval; + +@@ -4443,8 +4461,10 @@ static void idle_balance(int this_cpu, struct rq *this_rq) + interval = msecs_to_jiffies(sd->balance_interval); + if (time_after(next_balance, sd->last_balance + interval)) + next_balance = sd->last_balance + interval; +- if (pulled_task) ++ if (pulled_task) { ++ this_rq->idle_stamp = 0; + break; ++ } + } + if (pulled_task || time_after(jiffies, this_rq->next_balance)) { + /* +@@ -9522,6 +9542,8 @@ void __init sched_init(void) + rq->cpu = i; + rq->online = 0; + rq->migration_thread = NULL; ++ rq->idle_stamp = 0; ++ rq->avg_idle = 2*sysctl_sched_migration_cost; + INIT_LIST_HEAD(&rq->migration_queue); + rq_attach_root(rq, &def_root_domain); + #endif +diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c +index efb8440..6988cf0 100644 +--- a/kernel/sched_debug.c ++++ b/kernel/sched_debug.c +@@ -285,12 +285,16 @@ static void print_cpu(struct seq_file *m, int cpu) + + #ifdef CONFIG_SCHEDSTATS + #define P(n) SEQ_printf(m, " .%-30s: %d\n", #n, rq->n); ++#define P64(n) SEQ_printf(m, " .%-30s: %Ld\n", #n, rq->n); + + P(yld_count); + + P(sched_switch); + P(sched_count); + P(sched_goidle); ++#ifdef CONFIG_SMP ++ P64(avg_idle); ++#endif + + P(ttwu_count); + P(ttwu_local); +diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c +index 37087a7..5488a5d 100644 +--- a/kernel/sched_fair.c ++++ b/kernel/sched_fair.c +@@ -1398,11 +1398,38 @@ static int select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flag + want_sd = 0; + } + +- if (want_affine && (tmp->flags & SD_WAKE_AFFINE) && +- cpumask_test_cpu(prev_cpu, sched_domain_span(tmp))) { ++ if (want_affine && (tmp->flags & SD_WAKE_AFFINE)) { ++ int candidate = -1, i; + +- affine_sd = tmp; +- want_affine = 0; ++ if (cpumask_test_cpu(prev_cpu, sched_domain_span(tmp))) ++ candidate = cpu; ++ ++ /* ++ * Check for an idle shared cache. ++ */ ++ if (tmp->flags & SD_PREFER_SIBLING) { ++ if (candidate == cpu) { ++ if (!cpu_rq(prev_cpu)->cfs.nr_running) ++ candidate = prev_cpu; ++ } ++ ++ if (candidate == -1 || candidate == cpu) { ++ for_each_cpu(i, sched_domain_span(tmp)) { ++ if (!cpumask_test_cpu(i, &p->cpus_allowed)) ++ continue; ++ if (!cpu_rq(i)->cfs.nr_running) { ++ candidate = i; ++ break; ++ } ++ } ++ } ++ } ++ ++ if (candidate >= 0) { ++ affine_sd = tmp; ++ want_affine = 0; ++ cpu = candidate; ++ } + } + + if (!want_sd && !want_affine) +diff --git a/mm/memcontrol.c b/mm/memcontrol.c +index f99f599..6314015 100644 +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -2541,6 +2541,7 @@ static u64 mem_cgroup_read(struct cgroup *cont, struct cftype *cft) + val += idx_val; + mem_cgroup_get_recursive_idx_stat(mem, + MEM_CGROUP_STAT_SWAPOUT, &idx_val); ++ val += idx_val; + val <<= PAGE_SHIFT; + } else + val = res_counter_read_u64(&mem->memsw, name); +diff --git a/mm/memory.c b/mm/memory.c +index 6ab19dd..4e59455 100644 +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -2514,7 +2514,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, + ret = VM_FAULT_HWPOISON; + } else { + print_bad_pte(vma, address, orig_pte, NULL); +- ret = VM_FAULT_OOM; ++ ret = VM_FAULT_SIGBUS; + } + goto out; + } +@@ -2910,7 +2910,7 @@ static int do_nonlinear_fault(struct mm_struct *mm, struct vm_area_struct *vma, + * Page table corrupted: show pte and kill process. + */ + print_bad_pte(vma, address, orig_pte, NULL); +- return VM_FAULT_OOM; ++ return VM_FAULT_SIGBUS; + } + + pgoff = pte_to_pgoff(orig_pte); +diff --git a/mm/mincore.c b/mm/mincore.c +index 8cb508f..7a3436e 100644 +--- a/mm/mincore.c ++++ b/mm/mincore.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -72,6 +73,42 @@ static long do_mincore(unsigned long addr, unsigned char *vec, unsigned long pag + if (!vma || addr < vma->vm_start) + return -ENOMEM; + ++#ifdef CONFIG_HUGETLB_PAGE ++ if (is_vm_hugetlb_page(vma)) { ++ struct hstate *h; ++ unsigned long nr_huge; ++ unsigned char present; ++ ++ i = 0; ++ nr = min(pages, (vma->vm_end - addr) >> PAGE_SHIFT); ++ h = hstate_vma(vma); ++ nr_huge = ((addr + pages * PAGE_SIZE - 1) >> huge_page_shift(h)) ++ - (addr >> huge_page_shift(h)) + 1; ++ nr_huge = min(nr_huge, ++ (vma->vm_end - addr) >> huge_page_shift(h)); ++ while (1) { ++ /* hugepage always in RAM for now, ++ * but generally it needs to be check */ ++ ptep = huge_pte_offset(current->mm, ++ addr & huge_page_mask(h)); ++ present = !!(ptep && ++ !huge_pte_none(huge_ptep_get(ptep))); ++ while (1) { ++ vec[i++] = present; ++ addr += PAGE_SIZE; ++ /* reach buffer limit */ ++ if (i == nr) ++ return nr; ++ /* check hugepage border */ ++ if (!((addr & ~huge_page_mask(h)) ++ >> PAGE_SHIFT)) ++ break; ++ } ++ } ++ return nr; ++ } ++#endif ++ + /* + * Calculate how many pages there are left in the last level of the + * PTE array for our address. +diff --git a/mm/pagewalk.c b/mm/pagewalk.c +index d5878be..a286915 100644 +--- a/mm/pagewalk.c ++++ b/mm/pagewalk.c +@@ -1,6 +1,7 @@ + #include + #include + #include ++#include + + static int walk_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, + struct mm_walk *walk) +@@ -107,6 +108,7 @@ int walk_page_range(unsigned long addr, unsigned long end, + pgd_t *pgd; + unsigned long next; + int err = 0; ++ struct vm_area_struct *vma; + + if (addr >= end) + return err; +@@ -117,11 +119,22 @@ int walk_page_range(unsigned long addr, unsigned long end, + pgd = pgd_offset(walk->mm, addr); + do { + next = pgd_addr_end(addr, end); ++ ++ /* skip hugetlb vma to avoid hugepage PMD being cleared ++ * in pmd_none_or_clear_bad(). */ ++ vma = find_vma(walk->mm, addr); ++ if (vma && is_vm_hugetlb_page(vma)) { ++ if (vma->vm_end < next) ++ next = vma->vm_end; ++ continue; ++ } ++ + if (pgd_none_or_clear_bad(pgd)) { + if (walk->pte_hole) + err = walk->pte_hole(addr, next, walk); + if (err) + break; ++ pgd++; + continue; + } + if (walk->pgd_entry) +@@ -131,7 +144,8 @@ int walk_page_range(unsigned long addr, unsigned long end, + err = walk_pud_range(pgd, addr, next, walk); + if (err) + break; +- } while (pgd++, addr = next, addr != end); ++ pgd++; ++ } while (addr = next, addr != end); + + return err; + } +diff --git a/mm/vmalloc.c b/mm/vmalloc.c +index 0f551a4..7758726 100644 +--- a/mm/vmalloc.c ++++ b/mm/vmalloc.c +@@ -1993,6 +1993,7 @@ void free_vm_area(struct vm_struct *area) + } + EXPORT_SYMBOL_GPL(free_vm_area); + ++#ifndef CONFIG_HAVE_LEGACY_PER_CPU_AREA + static struct vmap_area *node_to_va(struct rb_node *n) + { + return n ? rb_entry(n, struct vmap_area, rb_node) : NULL; +@@ -2257,6 +2258,7 @@ err_free: + kfree(vms); + return NULL; + } ++#endif + + /** + * pcpu_free_vm_areas - free vmalloc areas for percpu allocator +diff --git a/net/core/dev.c b/net/core/dev.c +index fe10551..584046e 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -4860,6 +4860,11 @@ int register_netdevice(struct net_device *dev) + rollback_registered(dev); + dev->reg_state = NETREG_UNREGISTERED; + } ++ /* ++ * Prevent userspace races by waiting until the network ++ * device is fully setup before sending notifications. ++ */ ++ rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U); + + out: + return ret; +@@ -5398,6 +5403,12 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char + /* Notify protocols, that a new device appeared. */ + call_netdevice_notifiers(NETDEV_REGISTER, dev); + ++ /* ++ * Prevent userspace races by waiting until the network ++ * device is fully setup before sending notifications. ++ */ ++ rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U); ++ + synchronize_net(); + err = 0; + out: +diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c +index eb42873..d4fd895 100644 +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -1334,13 +1334,11 @@ static int rtnetlink_event(struct notifier_block *this, unsigned long event, voi + case NETDEV_UNREGISTER: + rtmsg_ifinfo(RTM_DELLINK, dev, ~0U); + break; +- case NETDEV_REGISTER: +- rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U); +- break; + case NETDEV_UP: + case NETDEV_DOWN: + rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); + break; ++ case NETDEV_REGISTER: + case NETDEV_CHANGE: + case NETDEV_GOING_DOWN: + break; +diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c +index f989518..4d50daa 100644 +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -501,8 +501,8 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) + if (skb->sk) { + frag->sk = skb->sk; + frag->destructor = sock_wfree; +- truesizes += frag->truesize; + } ++ truesizes += frag->truesize; + } + + /* Everything is OK. Generate! */ +diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c +index 7b5131b..cca675e 100644 +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -338,7 +338,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) + sinfo->rx_packets = sta->rx_packets; + sinfo->tx_packets = sta->tx_packets; + +- if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) { ++ if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || ++ (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { + sinfo->filled |= STATION_INFO_SIGNAL; + sinfo->signal = (s8)sta->last_signal; + } +diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h +index 10d316e..5a46164 100644 +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -808,6 +808,7 @@ struct ieee80211_local { + unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ + + bool pspolling; ++ bool scan_ps_enabled; + /* + * PS can only be enabled when we have exactly one managed + * interface (and monitors) in PS, this then points there. +diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h +index dd1c193..010ff2f 100644 +--- a/net/mac80211/mesh.h ++++ b/net/mac80211/mesh.h +@@ -186,8 +186,9 @@ struct mesh_rmc { + */ + #define MESH_PREQ_MIN_INT 10 + #define MESH_DIAM_TRAVERSAL_TIME 50 +-/* Paths will be refreshed if they are closer than PATH_REFRESH_TIME to their +- * expiration ++/* A path will be refreshed if it is used PATH_REFRESH_TIME milliseconds before ++ * timing out. This way it will remain ACTIVE and no data frames will be ++ * unnecesarily held in the pending queue. + */ + #define MESH_PATH_REFRESH_TIME 1000 + #define MESH_MIN_DISCOVERY_TIMEOUT (2 * MESH_DIAM_TRAVERSAL_TIME) +diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c +index 29b82e9..93c49fc 100644 +--- a/net/mac80211/mesh_hwmp.c ++++ b/net/mac80211/mesh_hwmp.c +@@ -813,7 +813,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb, + } + + if (mpath->flags & MESH_PATH_ACTIVE) { +- if (time_after(jiffies, mpath->exp_time + ++ if (time_after(jiffies, mpath->exp_time - + msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) + && !memcmp(sdata->dev->dev_addr, hdr->addr4, + ETH_ALEN) +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index 7170bf4..4e14754 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1514,7 +1514,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) + mpp_path_add(mesh_hdr->eaddr2, hdr->addr4, sdata); + } else { + spin_lock_bh(&mppath->state_lock); +- mppath->exp_time = jiffies; + if (compare_ether_addr(mppath->mpp, hdr->addr4) != 0) + memcpy(mppath->mpp, hdr->addr4, ETH_ALEN); + spin_unlock_bh(&mppath->state_lock); +diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c +index 71e10ca..1a41909 100644 +--- a/net/mac80211/scan.c ++++ b/net/mac80211/scan.c +@@ -196,7 +196,8 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) + static void ieee80211_scan_ps_enable(struct ieee80211_sub_if_data *sdata) + { + struct ieee80211_local *local = sdata->local; +- bool ps = false; ++ ++ local->scan_ps_enabled = false; + + /* FIXME: what to do when local->pspolling is true? */ + +@@ -204,12 +205,13 @@ static void ieee80211_scan_ps_enable(struct ieee80211_sub_if_data *sdata) + cancel_work_sync(&local->dynamic_ps_enable_work); + + if (local->hw.conf.flags & IEEE80211_CONF_PS) { +- ps = true; ++ local->scan_ps_enabled = true; + local->hw.conf.flags &= ~IEEE80211_CONF_PS; + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); + } + +- if (!ps || !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)) ++ if (!(local->scan_ps_enabled) || ++ !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)) + /* + * If power save was enabled, no need to send a nullfunc + * frame because AP knows that we are sleeping. But if the +@@ -230,7 +232,7 @@ static void ieee80211_scan_ps_disable(struct ieee80211_sub_if_data *sdata) + + if (!local->ps_sdata) + ieee80211_send_nullfunc(local, sdata, 0); +- else { ++ else if (local->scan_ps_enabled) { + /* + * In !IEEE80211_HW_PS_NULLFUNC_STACK case the hardware + * will send a nullfunc frame with the powersave bit set +@@ -246,6 +248,16 @@ static void ieee80211_scan_ps_disable(struct ieee80211_sub_if_data *sdata) + */ + local->hw.conf.flags |= IEEE80211_CONF_PS; + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); ++ } else if (local->hw.conf.dynamic_ps_timeout > 0) { ++ /* ++ * If IEEE80211_CONF_PS was not set and the dynamic_ps_timer ++ * had been running before leaving the operating channel, ++ * restart the timer now and send a nullfunc frame to inform ++ * the AP that we are awake. ++ */ ++ ieee80211_send_nullfunc(local, sdata, 0); ++ mod_timer(&local->dynamic_ps_timer, jiffies + ++ msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); + } + } + +@@ -264,10 +276,14 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) + + mutex_lock(&local->scan_mtx); + +- if (WARN_ON(!local->scanning)) { +- mutex_unlock(&local->scan_mtx); +- return; +- } ++ /* ++ * It's ok to abort a not-yet-running scan (that ++ * we have one at all will be verified by checking ++ * local->scan_req next), but not to complete it ++ * successfully. ++ */ ++ if (WARN_ON(!local->scanning && !aborted)) ++ aborted = true; + + if (WARN_ON(!local->scan_req)) { + mutex_unlock(&local->scan_mtx); +diff --git a/net/mac80211/util.c b/net/mac80211/util.c +index e6c08da..cbc5d20 100644 +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -579,7 +579,7 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, + if (elen > left) + break; + +- if (calc_crc && id < 64 && (filter & BIT(id))) ++ if (calc_crc && id < 64 && (filter & (1ULL << id))) + crc = crc32_be(crc, pos - 2, elen + 2); + + switch (id) { +diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c +index 446e9bd..02b2610 100644 +--- a/net/netfilter/ipvs/ip_vs_ctl.c ++++ b/net/netfilter/ipvs/ip_vs_ctl.c +@@ -2714,6 +2714,8 @@ static int ip_vs_genl_parse_service(struct ip_vs_service_user_kern *usvc, + if (!(nla_af && (nla_fwmark || (nla_port && nla_protocol && nla_addr)))) + return -EINVAL; + ++ memset(usvc, 0, sizeof(*usvc)); ++ + usvc->af = nla_get_u16(nla_af); + #ifdef CONFIG_IP_VS_IPV6 + if (usvc->af != AF_INET && usvc->af != AF_INET6) +@@ -2901,6 +2903,8 @@ static int ip_vs_genl_parse_dest(struct ip_vs_dest_user_kern *udest, + if (!(nla_addr && nla_port)) + return -EINVAL; + ++ memset(udest, 0, sizeof(*udest)); ++ + nla_memcpy(&udest->addr, nla_addr, sizeof(udest->addr)); + udest->port = nla_get_u16(nla_port); + +diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c +index fc6a43c..129d75e 100644 +--- a/net/sunrpc/auth_gss/auth_gss.c ++++ b/net/sunrpc/auth_gss/auth_gss.c +@@ -485,7 +485,7 @@ gss_refresh_upcall(struct rpc_task *task) + dprintk("RPC: %5u gss_refresh_upcall for uid %u\n", task->tk_pid, + cred->cr_uid); + gss_msg = gss_setup_upcall(task->tk_client, gss_auth, cred); +- if (IS_ERR(gss_msg) == -EAGAIN) { ++ if (PTR_ERR(gss_msg) == -EAGAIN) { + /* XXX: warning on the first, under the assumption we + * shouldn't normally hit this case on a refresh. */ + warn_gssd(); +diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c +index 34c7d48..7f4d744 100644 +--- a/sound/core/hrtimer.c ++++ b/sound/core/hrtimer.c +@@ -37,14 +37,22 @@ static unsigned int resolution; + struct snd_hrtimer { + struct snd_timer *timer; + struct hrtimer hrt; ++ atomic_t running; + }; + + static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt) + { + struct snd_hrtimer *stime = container_of(hrt, struct snd_hrtimer, hrt); + struct snd_timer *t = stime->timer; ++ ++ if (!atomic_read(&stime->running)) ++ return HRTIMER_NORESTART; ++ + hrtimer_forward_now(hrt, ns_to_ktime(t->sticks * resolution)); + snd_timer_interrupt(stime->timer, t->sticks); ++ ++ if (!atomic_read(&stime->running)) ++ return HRTIMER_NORESTART; + return HRTIMER_RESTART; + } + +@@ -58,6 +66,7 @@ static int snd_hrtimer_open(struct snd_timer *t) + hrtimer_init(&stime->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + stime->timer = t; + stime->hrt.function = snd_hrtimer_callback; ++ atomic_set(&stime->running, 0); + t->private_data = stime; + return 0; + } +@@ -78,16 +87,18 @@ static int snd_hrtimer_start(struct snd_timer *t) + { + struct snd_hrtimer *stime = t->private_data; + ++ atomic_set(&stime->running, 0); ++ hrtimer_cancel(&stime->hrt); + hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution), + HRTIMER_MODE_REL); ++ atomic_set(&stime->running, 1); + return 0; + } + + static int snd_hrtimer_stop(struct snd_timer *t) + { + struct snd_hrtimer *stime = t->private_data; +- +- hrtimer_cancel(&stime->hrt); ++ atomic_set(&stime->running, 0); + return 0; + } + +diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c +index 6517f58..7e4ee4e 100644 +--- a/sound/pci/hda/hda_intel.c ++++ b/sound/pci/hda/hda_intel.c +@@ -2436,6 +2436,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, + } + } + ++ /* disable 64bit DMA address for Teradici */ ++ /* it does not work with device 6549:1200 subsys e4a2:040b */ ++ if (chip->driver_type == AZX_DRIVER_TERA) ++ gcap &= ~ICH6_GCAP_64OK; ++ + /* allow 64bit DMA address if supported by H/W */ + if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) + pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64)); +diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c +index 001663f..03e5b21 100644 +--- a/virt/kvm/irq_comm.c ++++ b/virt/kvm/irq_comm.c +@@ -205,10 +205,9 @@ int kvm_request_irq_source_id(struct kvm *kvm) + int irq_source_id; + + mutex_lock(&kvm->irq_lock); +- irq_source_id = find_first_zero_bit(bitmap, +- sizeof(kvm->arch.irq_sources_bitmap)); ++ irq_source_id = find_first_zero_bit(bitmap, BITS_PER_LONG); + +- if (irq_source_id >= sizeof(kvm->arch.irq_sources_bitmap)) { ++ if (irq_source_id >= BITS_PER_LONG) { + printk(KERN_WARNING "kvm: exhaust allocatable IRQ sources!\n"); + return -EFAULT; + } +@@ -228,7 +227,7 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id) + + mutex_lock(&kvm->irq_lock); + if (irq_source_id < 0 || +- irq_source_id >= sizeof(kvm->arch.irq_sources_bitmap)) { ++ irq_source_id >= BITS_PER_LONG) { + printk(KERN_ERR "kvm: IRQ source ID out of range!\n"); + return; + } diff --git a/debian/patches/series/3 b/debian/patches/series/3 index acc4cc73a..e1ddff455 100644 --- a/debian/patches/series/3 +++ b/debian/patches/series/3 @@ -4,3 +4,5 @@ + features/all/gro-Change-all-receive-functions-to-return-GRO-result.patch + features/all/ethtool-Add-reset-operation.patch + features/all/sfc-2.6.33-rc1.patch +- bugfix/mips/drm-ttm-build-fix.patch ++ bugfix/all/stable/2.6.32.2.patch