diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c index d51bc8b..b4565bb 100644 --- a/arch/arm/kernel/kprobes-decode.c +++ b/arch/arm/kernel/kprobes-decode.c @@ -1176,7 +1176,7 @@ space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi) * *S (bit 20) updates condition codes * ADC/SBC/RSC reads the C flag */ - insn &= 0xfff00ff0; /* Rn = r0, Rd = r0 */ + insn &= 0xfff00fff; /* Rn = r0, Rd = r0 */ asi->insn[0] = insn; asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */ emulate_alu_imm_rwflags : emulate_alu_imm_rflags; diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c index 13e371a..5593dd2 100644 --- a/arch/arm/kernel/kprobes.c +++ b/arch/arm/kernel/kprobes.c @@ -66,7 +66,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) return -ENOMEM; for (is = 0; is < MAX_INSN_SIZE; ++is) p->ainsn.insn[is] = tmp_insn[is]; - flush_insns(&p->ainsn.insn, MAX_INSN_SIZE); + flush_insns(p->ainsn.insn, MAX_INSN_SIZE); break; case INSN_GOOD_NO_SLOT: /* instruction doesn't need insn slot */ diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c index 42bf09d..9f8c8e1 100644 --- a/arch/sparc/kernel/sys_sparc.c +++ b/arch/sparc/kernel/sys_sparc.c @@ -224,8 +224,7 @@ int sparc_mmap_check(unsigned long addr, unsigned long len, unsigned long flags) { if (ARCH_SUN4C_SUN4 && (len > 0x20000000 || - ((flags & MAP_FIXED) && - addr < 0xe0000000 && addr + len > 0x20000000))) + (addr < 0xe0000000 && addr + len > 0x20000000))) return -EINVAL; /* See asm-sparc/uaccess.h */ diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index f952745..cc37936 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c @@ -549,13 +549,13 @@ int sparc64_mmap_check(unsigned long addr, unsigned long len, if (len >= STACK_TOP32) return -EINVAL; - if ((flags & MAP_FIXED) && addr > STACK_TOP32 - len) + if (addr > STACK_TOP32 - len) return -EINVAL; } else { if (len >= VA_EXCLUDE_START) return -EINVAL; - if ((flags & MAP_FIXED) && invalid_64bit_range(addr, len)) + if (invalid_64bit_range(addr, len)) return -EINVAL; } diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 7b6e3bb..05356ce 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c @@ -372,13 +372,16 @@ static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { {} }; +void __init dmi_check_pciprobe(void) +{ + dmi_check_system(pciprobe_dmi_table); +} + struct pci_bus * __devinit pcibios_scan_root(int busnum) { struct pci_bus *bus = NULL; struct pci_sysdata *sd; - dmi_check_system(pciprobe_dmi_table); - while ((bus = pci_find_next_bus(bus)) != NULL) { if (bus->number == busnum) { /* Already scanned */ diff --git a/arch/x86/pci/init.c b/arch/x86/pci/init.c index 3de9f9b..f1bf4e5 100644 --- a/arch/x86/pci/init.c +++ b/arch/x86/pci/init.c @@ -32,6 +32,8 @@ static __init int pci_access_init(void) printk(KERN_ERR "PCI: Fatal: No config space access function found\n"); + dmi_check_pciprobe(); + return 0; } arch_initcall(pci_access_init); diff --git a/arch/x86/pci/pci.h b/arch/x86/pci/pci.h index 3431518..95e5675 100644 --- a/arch/x86/pci/pci.h +++ b/arch/x86/pci/pci.h @@ -39,6 +39,8 @@ enum pci_bf_sort_state { pci_dmi_bf, }; +extern void __init dmi_check_pciprobe(void); + /* pci-i386.c */ extern unsigned int pcibios_max_latency; diff --git a/crypto/authenc.c b/crypto/authenc.c index ed8ac5a..4b22676 100644 --- a/crypto/authenc.c +++ b/crypto/authenc.c @@ -217,9 +217,10 @@ static void crypto_authenc_givencrypt_done(struct crypto_async_request *req, int err) { if (!err) { - struct aead_givcrypt_request *greq = req->data; + struct aead_request *areq = req->data; + struct skcipher_givcrypt_request *greq = aead_request_ctx(areq); - err = crypto_authenc_genicv(&greq->areq, greq->giv, 0); + err = crypto_authenc_genicv(areq, greq->giv, 0); } aead_request_complete(req->data, err); diff --git a/crypto/cryptd.c b/crypto/cryptd.c index 2504252..b150de5 100644 --- a/crypto/cryptd.c +++ b/crypto/cryptd.c @@ -190,8 +190,10 @@ static struct crypto_instance *cryptd_alloc_instance(struct crypto_alg *alg, int err; inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); - if (IS_ERR(inst)) + if (!inst) { + inst = ERR_PTR(-ENOMEM); goto out; + } err = -ENAMETOOLONG; if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, diff --git a/crypto/eseqiv.c b/crypto/eseqiv.c index b14f14e..881d309 100644 --- a/crypto/eseqiv.c +++ b/crypto/eseqiv.c @@ -136,7 +136,8 @@ static int eseqiv_givencrypt(struct skcipher_givcrypt_request *req) } ablkcipher_request_set_crypt(subreq, reqctx->src, dst, - req->creq.nbytes, req->creq.info); + req->creq.nbytes + ivsize, + req->creq.info); memcpy(req->creq.info, ctx->salt, ivsize); diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 788da97..836362b 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -848,6 +848,7 @@ static int acpi_processor_get_power_info_default(struct acpi_processor *pr) /* all processors need to support C1 */ pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; pr->power.states[ACPI_STATE_C1].valid = 1; + pr->power.states[ACPI_STATE_C1].entry_method = ACPI_CSTATE_HALT; } /* the C0 state only exists as a filler in our array */ pr->power.states[ACPI_STATE_C0].valid = 1; @@ -960,6 +961,9 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) cx.address); } + if (cx.type == ACPI_STATE_C1) { + cx.valid = 1; + } obj = &(element->package.elements[2]); if (obj->type != ACPI_TYPE_INTEGER) diff --git a/drivers/md/md.c b/drivers/md/md.c index 61ccbd2..9f6d228 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2096,7 +2096,7 @@ rdev_attr_store(struct kobject *kobj, struct attribute *attr, rv = -EBUSY; else rv = entry->store(rdev, page, length); - mddev_unlock(rdev->mddev); + mddev_unlock(mddev); } return rv; } diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index f13346b..44ebdea 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -628,6 +628,10 @@ struct b43_wl { struct mutex mutex; spinlock_t irq_lock; + /* R/W lock for data transmission. + * Transmissions on 2+ queues can run concurrently, but somebody else + * might sync with TX by write_lock_irqsave()'ing. */ + rwlock_t tx_lock; /* Lock for LEDs access. */ spinlock_t leds_lock; /* Lock for SHM access. */ diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index f23317e..e0055d0 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -622,6 +622,7 @@ static void b43_synchronize_irq(struct b43_wldev *dev) */ void b43_dummy_transmission(struct b43_wldev *dev) { + struct b43_wl *wl = dev->wl; struct b43_phy *phy = &dev->phy; unsigned int i, max_loop; u16 value; @@ -648,6 +649,9 @@ void b43_dummy_transmission(struct b43_wldev *dev) return; } + spin_lock_irq(&wl->irq_lock); + write_lock(&wl->tx_lock); + for (i = 0; i < 5; i++) b43_ram_write(dev, i * 4, buffer[i]); @@ -688,6 +692,9 @@ void b43_dummy_transmission(struct b43_wldev *dev) } if (phy->radio_ver == 0x2050 && phy->radio_rev <= 0x5) b43_radio_write16(dev, 0x0051, 0x0037); + + write_unlock(&wl->tx_lock); + spin_unlock_irq(&wl->irq_lock); } static void key_write(struct b43_wldev *dev, @@ -2592,15 +2599,21 @@ static int b43_op_tx(struct ieee80211_hw *hw, { struct b43_wl *wl = hw_to_b43_wl(hw); struct b43_wldev *dev = wl->current_dev; - int err = -ENODEV; + unsigned long flags; + int err; if (unlikely(!dev)) - goto out; - if (unlikely(b43_status(dev) < B43_STAT_STARTED)) - goto out; - /* DMA-TX is done without a global lock. */ - err = b43_dma_tx(dev, skb, ctl); -out: + return NETDEV_TX_BUSY; + + /* Transmissions on seperate queues can run concurrently. */ + read_lock_irqsave(&wl->tx_lock, flags); + + err = -ENODEV; + if (likely(b43_status(dev) >= B43_STAT_STARTED)) + err = b43_dma_tx(dev, skb, ctl); + + read_unlock_irqrestore(&wl->tx_lock, flags); + if (unlikely(err)) return NETDEV_TX_BUSY; return NETDEV_TX_OK; @@ -3109,7 +3122,9 @@ static void b43_wireless_core_stop(struct b43_wldev *dev) spin_unlock_irqrestore(&wl->irq_lock, flags); b43_synchronize_irq(dev); + write_lock_irqsave(&wl->tx_lock, flags); b43_set_status(dev, B43_STAT_INITIALIZED); + write_unlock_irqrestore(&wl->tx_lock, flags); mutex_unlock(&wl->mutex); /* Must unlock as it would otherwise deadlock. No races here. @@ -3117,8 +3132,6 @@ static void b43_wireless_core_stop(struct b43_wldev *dev) cancel_delayed_work_sync(&dev->periodic_work); mutex_lock(&wl->mutex); - ieee80211_stop_queues(wl->hw); //FIXME this could cause a deadlock, as mac80211 seems buggy. - b43_mac_suspend(dev); free_irq(dev->dev->irq, dev); b43dbg(wl, "Wireless interface stopped\n"); @@ -3912,6 +3925,14 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) err = -EOPNOTSUPP; goto err_powerdown; } + if (1 /* disable A-PHY */) { + /* FIXME: For now we disable the A-PHY on multi-PHY devices. */ + if (dev->phy.type != B43_PHYTYPE_N) { + have_2ghz_phy = 1; + have_5ghz_phy = 0; + } + } + dev->phy.gmode = have_2ghz_phy; tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0; b43_wireless_core_reset(dev, tmp); @@ -4076,6 +4097,7 @@ static int b43_wireless_init(struct ssb_device *dev) memset(wl, 0, sizeof(*wl)); wl->hw = hw; spin_lock_init(&wl->irq_lock); + rwlock_init(&wl->tx_lock); spin_lock_init(&wl->leds_lock); spin_lock_init(&wl->shm_lock); mutex_init(&wl->mutex); diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index d93b357..7a3625f 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c @@ -1221,8 +1221,8 @@ static struct of_device_id mpc52xx_uart_of_match[] = { #endif #ifdef CONFIG_PPC_MPC512x { .compatible = "fsl,mpc5121-psc-uart", .data = &mpc512x_psc_ops, }, - {}, #endif + {}, }; static int __devinit diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c index e0f0f09..9f877ab 100644 --- a/fs/reiserfs/ioctl.c +++ b/fs/reiserfs/ioctl.c @@ -11,8 +11,6 @@ #include #include -static int reiserfs_unpack(struct inode *inode, struct file *filp); - /* ** reiserfs_ioctl - handler for ioctl for inode ** supported commands: @@ -140,7 +138,7 @@ int reiserfs_prepare_write(struct file *f, struct page *page, ** Function try to convert tail from direct item into indirect. ** It set up nopack attribute in the REISERFS_I(inode)->nopack */ -static int reiserfs_unpack(struct inode *inode, struct file *filp) +int reiserfs_unpack(struct inode *inode, struct file *filp) { int retval = 0; int index; diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 393cc22..3302259 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -2019,6 +2019,7 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, { int err; struct nameidata nd; + struct inode *inode; if (!(REISERFS_SB(sb)->s_mount_opt & (1 << REISERFS_QUOTA))) return -EINVAL; @@ -2030,12 +2031,18 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, path_put(&nd.path); return -EXDEV; } + inode = nd.path.dentry->d_inode; /* We must not pack tails for quota files on reiserfs for quota IO to work */ - if (!(REISERFS_I(nd.path.dentry->d_inode)->i_flags & i_nopack_mask)) { - reiserfs_warning(sb, - "reiserfs: Quota file must have tail packing disabled."); - path_put(&nd.path); - return -EINVAL; + if (!(REISERFS_I(inode)->i_flags & i_nopack_mask)) { + err = reiserfs_unpack(inode, NULL); + if (err) { + reiserfs_warning(sb, + "reiserfs: Unpacking tail of quota file failed" + " (%d). Cannot turn on quotas.", err); + path_put(&nd.path); + return -EINVAL; + } + mark_inode_dirty(inode); } /* Not journalling quota? No more tests needed... */ if (!REISERFS_SB(sb)->s_qf_names[USRQUOTA] && diff --git a/fs/utimes.c b/fs/utimes.c index b18da9c..80a481e 100644 --- a/fs/utimes.c +++ b/fs/utimes.c @@ -39,9 +39,14 @@ asmlinkage long sys_utime(char __user *filename, struct utimbuf __user *times) #endif +static bool nsec_special(long nsec) +{ + return nsec == UTIME_OMIT || nsec == UTIME_NOW; +} + static bool nsec_valid(long nsec) { - if (nsec == UTIME_OMIT || nsec == UTIME_NOW) + if (nsec_special(nsec)) return true; return nsec >= 0 && nsec <= 999999999; @@ -115,7 +120,15 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags newattrs.ia_mtime.tv_nsec = times[1].tv_nsec; newattrs.ia_valid |= ATTR_MTIME_SET; } - } else { + } + + /* + * If times is NULL or both times are either UTIME_OMIT or + * UTIME_NOW, then need to check permissions, because + * inode_change_ok() won't do it. + */ + if (!times || (nsec_special(times[0].tv_nsec) && + nsec_special(times[1].tv_nsec))) { error = -EACCES; if (IS_IMMUTABLE(inode)) goto dput_and_out; diff --git a/include/crypto/scatterwalk.h b/include/crypto/scatterwalk.h index 224658b..833d208 100644 --- a/include/crypto/scatterwalk.h +++ b/include/crypto/scatterwalk.h @@ -57,10 +57,14 @@ static inline void scatterwalk_sg_chain(struct scatterlist *sg1, int num, struct scatterlist *sg2) { sg_set_page(&sg1[num - 1], (void *)sg2, 0, 0); + sg1[num - 1].page_link &= ~0x02; } static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg) { + if (sg_is_last(sg)) + return NULL; + return (++sg)->length ? sg : (void *)sg_page(sg); } diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h index 8e7eff2..4aacaee 100644 --- a/include/linux/reiserfs_fs.h +++ b/include/linux/reiserfs_fs.h @@ -2176,6 +2176,7 @@ int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); long reiserfs_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +int reiserfs_unpack(struct inode *inode, struct file *filp); /* ioctl's command */ #define REISERFS_IOC_UNPACK _IOW(0xCD,1,long) diff --git a/kernel/sched.c b/kernel/sched.c index 8dcdec6..1e4596c 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -876,6 +876,7 @@ static inline void resched_rq(struct rq *rq) enum { HRTICK_SET, /* re-programm hrtick_timer */ HRTICK_RESET, /* not a new slice */ + HRTICK_BLOCK, /* stop hrtick operations */ }; /* @@ -887,6 +888,8 @@ static inline int hrtick_enabled(struct rq *rq) { if (!sched_feat(HRTICK)) return 0; + if (unlikely(test_bit(HRTICK_BLOCK, &rq->hrtick_flags))) + return 0; return hrtimer_is_hres_active(&rq->hrtick_timer); } @@ -969,7 +972,63 @@ static enum hrtimer_restart hrtick(struct hrtimer *timer) return HRTIMER_NORESTART; } -static inline void init_rq_hrtick(struct rq *rq) +static void hotplug_hrtick_disable(int cpu) +{ + struct rq *rq = cpu_rq(cpu); + unsigned long flags; + + spin_lock_irqsave(&rq->lock, flags); + rq->hrtick_flags = 0; + __set_bit(HRTICK_BLOCK, &rq->hrtick_flags); + spin_unlock_irqrestore(&rq->lock, flags); + + hrtick_clear(rq); +} + +static void hotplug_hrtick_enable(int cpu) +{ + struct rq *rq = cpu_rq(cpu); + unsigned long flags; + + spin_lock_irqsave(&rq->lock, flags); + __clear_bit(HRTICK_BLOCK, &rq->hrtick_flags); + spin_unlock_irqrestore(&rq->lock, flags); +} + +static int +hotplug_hrtick(struct notifier_block *nfb, unsigned long action, void *hcpu) +{ + int cpu = (int)(long)hcpu; + + switch (action) { + case CPU_UP_CANCELED: + case CPU_UP_CANCELED_FROZEN: + case CPU_DOWN_PREPARE: + case CPU_DOWN_PREPARE_FROZEN: + case CPU_DEAD: + case CPU_DEAD_FROZEN: + hotplug_hrtick_disable(cpu); + return NOTIFY_OK; + + case CPU_UP_PREPARE: + case CPU_UP_PREPARE_FROZEN: + case CPU_DOWN_FAILED: + case CPU_DOWN_FAILED_FROZEN: + case CPU_ONLINE: + case CPU_ONLINE_FROZEN: + hotplug_hrtick_enable(cpu); + return NOTIFY_OK; + } + + return NOTIFY_DONE; +} + +static void init_hrtick(void) +{ + hotcpu_notifier(hotplug_hrtick, 0); +} + +static void init_rq_hrtick(struct rq *rq) { rq->hrtick_flags = 0; hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); @@ -1006,6 +1065,10 @@ static inline void init_rq_hrtick(struct rq *rq) void hrtick_resched(void) { } + +static inline void init_hrtick(void) +{ +} #endif /* @@ -7094,6 +7157,7 @@ void __init sched_init_smp(void) put_online_cpus(); /* XXX: Theoretical race here - CPU may be hotplugged now */ hotcpu_notifier(update_sched_domains, 0); + init_hrtick(); /* Move init over to a non-isolated CPU */ if (set_cpus_allowed(current, non_isolated_cpus) < 0) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 402a504..55443c2 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2518,7 +2518,9 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone, struct page *page; unsigned long end_pfn = start_pfn + size; unsigned long pfn; + struct zone *z; + z = &NODE_DATA(nid)->node_zones[zone]; for (pfn = start_pfn; pfn < end_pfn; pfn++) { /* * There can be holes in boot-time mem_map[]s @@ -2536,7 +2538,6 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone, init_page_count(page); reset_page_mapcount(page); SetPageReserved(page); - /* * Mark the block movable so that blocks are reserved for * movable at startup. This will force kernel allocations @@ -2545,8 +2546,15 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone, * kernel allocations are made. Later some blocks near * the start are marked MIGRATE_RESERVE by * setup_zone_migrate_reserve() + * + * bitmap is created for zone's valid pfn range. but memmap + * can be created for invalid pages (for alignment) + * check here not to call set_pageblock_migratetype() against + * pfn out of zone. */ - if ((pfn & (pageblock_nr_pages-1))) + if ((z->zone_start_pfn <= pfn) + && (pfn < z->zone_start_pfn + z->spanned_pages) + && !(pfn & (pageblock_nr_pages - 1))) set_pageblock_migratetype(page, MIGRATE_MOVABLE); INIT_LIST_HEAD(&page->lru); @@ -4460,6 +4468,8 @@ void set_pageblock_flags_group(struct page *page, unsigned long flags, pfn = page_to_pfn(page); bitmap = get_pageblock_bitmap(zone, pfn); bitidx = pfn_to_bitidx(zone, pfn); + VM_BUG_ON(pfn < zone->zone_start_pfn); + VM_BUG_ON(pfn >= zone->zone_start_pfn + zone->spanned_pages); for (; start_bitidx <= end_bitidx; start_bitidx++, value <<= 1) if (flags & value) diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 1656c00..4de86c4 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -446,9 +446,9 @@ static int ipip6_rcv(struct sk_buff *skb) } icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); - kfree_skb(skb); read_unlock(&ipip6_lock); out: + kfree_skb(skb); return 0; }