diff options
-rw-r--r-- | arch/i386/kernel/io_apic.c | 2 | ||||
-rw-r--r-- | arch/i386/kernel/vmi.c | 23 | ||||
-rw-r--r-- | arch/i386/mm/highmem.c | 2 | ||||
-rw-r--r-- | arch/x86_64/kernel/early-quirks.c | 2 | ||||
-rw-r--r-- | drivers/char/agp/intel-agp.c | 14 | ||||
-rw-r--r-- | drivers/net/tg3.c | 6 | ||||
-rw-r--r-- | drivers/pcmcia/omap_cf.c | 41 | ||||
-rw-r--r-- | fs/fuse/dir.c | 5 | ||||
-rw-r--r-- | fs/fuse/fuse_i.h | 5 | ||||
-rw-r--r-- | fs/fuse/inode.c | 2 | ||||
-rw-r--r-- | include/asm-generic/pgtable.h | 2 | ||||
-rw-r--r-- | include/asm-i386/paravirt.h | 3 | ||||
-rw-r--r-- | include/linux/hrtimer.h | 3 | ||||
-rw-r--r-- | kernel/hrtimer.c | 12 | ||||
-rw-r--r-- | kernel/irq/devres.c | 2 | ||||
-rw-r--r-- | kernel/sched.c | 36 | ||||
-rw-r--r-- | kernel/timer.c | 2 | ||||
-rw-r--r-- | net/ipv4/xfrm4_mode_beet.c | 26 | ||||
-rw-r--r-- | net/ipv6/route.c | 19 |
19 files changed, 120 insertions, 87 deletions
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index e4408ff4e674..b3ab8ffebd27 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -736,7 +736,7 @@ failed: return 0; } -int __init irqbalance_disable(char *str) +int __devinit irqbalance_disable(char *str) { irqbalance_disabled = 1; return 1; diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c index fb07a1aad225..edc339fa5038 100644 --- a/arch/i386/kernel/vmi.c +++ b/arch/i386/kernel/vmi.c @@ -69,6 +69,7 @@ struct { void (*flush_tlb)(int); void (*set_initial_ap_state)(int, int); void (*halt)(void); + void (*set_lazy_mode)(int mode); } vmi_ops; /* XXX move this to alternative.h */ @@ -574,6 +575,26 @@ vmi_startup_ipi_hook(int phys_apicid, unsigned long start_eip, } #endif +static void vmi_set_lazy_mode(int mode) +{ + static DEFINE_PER_CPU(int, lazy_mode); + + if (!vmi_ops.set_lazy_mode) + return; + + /* Modes should never nest or overlap */ + BUG_ON(__get_cpu_var(lazy_mode) && !(mode == PARAVIRT_LAZY_NONE || + mode == PARAVIRT_LAZY_FLUSH)); + + if (mode == PARAVIRT_LAZY_FLUSH) { + vmi_ops.set_lazy_mode(0); + vmi_ops.set_lazy_mode(__get_cpu_var(lazy_mode)); + } else { + vmi_ops.set_lazy_mode(mode); + __get_cpu_var(lazy_mode) = mode; + } +} + static inline int __init check_vmi_rom(struct vrom_header *rom) { struct pci_header *pci; @@ -804,7 +825,7 @@ static inline int __init activate_vmi(void) para_wrap(load_esp0, vmi_load_esp0, set_kernel_stack, UpdateKernelStack); para_fill(set_iopl_mask, SetIOPLMask); para_fill(io_delay, IODelay); - para_fill(set_lazy_mode, SetLazyMode); + para_wrap(set_lazy_mode, vmi_set_lazy_mode, set_lazy_mode, SetLazyMode); /* user and kernel flush are just handled with different flags to FlushTLB */ para_wrap(flush_tlb_user, vmi_flush_tlb_user, flush_tlb, FlushTLB); diff --git a/arch/i386/mm/highmem.c b/arch/i386/mm/highmem.c index bb2de1089add..ac70d09df7ee 100644 --- a/arch/i386/mm/highmem.c +++ b/arch/i386/mm/highmem.c @@ -42,6 +42,7 @@ void *kmap_atomic(struct page *page, enum km_type type) vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); set_pte(kmap_pte-idx, mk_pte(page, kmap_prot)); + arch_flush_lazy_mmu_mode(); return (void*) vaddr; } @@ -82,6 +83,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot)); + arch_flush_lazy_mmu_mode(); return (void*) vaddr; } diff --git a/arch/x86_64/kernel/early-quirks.c b/arch/x86_64/kernel/early-quirks.c index 148c6bcf5bb4..fede55a53995 100644 --- a/arch/x86_64/kernel/early-quirks.c +++ b/arch/x86_64/kernel/early-quirks.c @@ -88,7 +88,7 @@ struct chipset { void (*f)(void); }; -static struct __initdata chipset early_qrk[] = { +static struct chipset early_qrk[] __initdata = { { PCI_VENDOR_ID_NVIDIA, nvidia_bugs }, { PCI_VENDOR_ID_VIA, via_bugs }, { PCI_VENDOR_ID_ATI, ati_bugs }, diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index e542a628f1c7..a9fdbf9126ca 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -18,11 +18,14 @@ #define PCI_DEVICE_ID_INTEL_82965Q_IG 0x2992 #define PCI_DEVICE_ID_INTEL_82965G_HB 0x29A0 #define PCI_DEVICE_ID_INTEL_82965G_IG 0x29A2 +#define PCI_DEVICE_ID_INTEL_82965GM_HB 0x2A00 +#define PCI_DEVICE_ID_INTEL_82965GM_IG 0x2A02 #define IS_I965 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82946GZ_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_1_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \ - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB) + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \ + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB) extern int agp_memory_reserved; @@ -1921,7 +1924,13 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, bridge->driver = &intel_845_driver; name = "965G"; break; - + case PCI_DEVICE_ID_INTEL_82965GM_HB: + if (find_i830(PCI_DEVICE_ID_INTEL_82965GM_IG)) + bridge->driver = &intel_i965_driver; + else + bridge->driver = &intel_845_driver; + name = "965GM"; + break; case PCI_DEVICE_ID_INTEL_7505_0: bridge->driver = &intel_7505_driver; name = "E7505"; @@ -2080,6 +2089,7 @@ static struct pci_device_id agp_intel_pci_table[] = { ID(PCI_DEVICE_ID_INTEL_82965G_1_HB), ID(PCI_DEVICE_ID_INTEL_82965Q_HB), ID(PCI_DEVICE_ID_INTEL_82965G_HB), + ID(PCI_DEVICE_ID_INTEL_82965GM_HB), { } }; diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 0acee9f324e9..256969e1300c 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -4834,8 +4834,10 @@ static int tg3_chip_reset(struct tg3 *tp) * sharing or irqpoll. */ tp->tg3_flags |= TG3_FLAG_CHIP_RESETTING; - tp->hw_status->status = 0; - tp->hw_status->status_tag = 0; + if (tp->hw_status) { + tp->hw_status->status = 0; + tp->hw_status->status_tag = 0; + } tp->last_tag = 0; smp_mb(); synchronize_irq(tp->pdev->irq); diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c index d77f75129f8a..2df216b00817 100644 --- a/drivers/pcmcia/omap_cf.c +++ b/drivers/pcmcia/omap_cf.c @@ -202,15 +202,14 @@ static struct pccard_operations omap_cf_ops = { * "what chipselect is used". Boards could want more. */ -static int __devinit omap_cf_probe(struct device *dev) +static int __init omap_cf_probe(struct platform_device *pdev) { unsigned seg; struct omap_cf_socket *cf; - struct platform_device *pdev = to_platform_device(dev); int irq; int status; - seg = (int) dev->platform_data; + seg = (int) pdev->dev.platform_data; if (seg == 0 || seg > 3) return -ENODEV; @@ -227,7 +226,7 @@ static int __devinit omap_cf_probe(struct device *dev) cf->timer.data = (unsigned long) cf; cf->pdev = pdev; - dev_set_drvdata(dev, cf); + platform_set_drvdata(pdev, cf); /* this primarily just shuts up irq handling noise */ status = request_irq(irq, omap_cf_irq, IRQF_SHARED, @@ -291,7 +290,7 @@ static int __devinit omap_cf_probe(struct device *dev) omap_cf_present() ? "present" : "(not present)"); cf->socket.owner = THIS_MODULE; - cf->socket.dev.parent = dev; + cf->socket.dev.parent = &pdev->dev; cf->socket.ops = &omap_cf_ops; cf->socket.resource_ops = &pccard_static_ops; cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP @@ -318,9 +317,9 @@ fail0: return status; } -static int __devexit omap_cf_remove(struct device *dev) +static int __exit omap_cf_remove(struct platform_device *pdev) { - struct omap_cf_socket *cf = dev_get_drvdata(dev); + struct omap_cf_socket *cf = platform_get_drvdata(pdev); cf->active = 0; pcmcia_unregister_socket(&cf->socket); @@ -332,26 +331,36 @@ static int __devexit omap_cf_remove(struct device *dev) return 0; } -static struct device_driver omap_cf_driver = { - .name = (char *) driver_name, - .bus = &platform_bus_type, - .probe = omap_cf_probe, - .remove = __devexit_p(omap_cf_remove), - .suspend = pcmcia_socket_dev_suspend, - .resume = pcmcia_socket_dev_resume, +static int omap_cf_suspend(struct platform_device *pdev, pm_message_t mesg) +{ + return pcmcia_socket_dev_suspend(&pdev->dev, mesg); +} + +static int omap_cf_resume(struct platform_device *pdev) +{ + return pcmcia_socket_dev_resume(&pdev->dev); +} + +static struct platform_driver omap_cf_driver = { + .driver = { + .name = (char *) driver_name, + }, + .remove = __exit_p(omap_cf_remove), + .suspend = omap_cf_suspend, + .resume = omap_cf_resume, }; static int __init omap_cf_init(void) { if (cpu_is_omap16xx()) - return driver_register(&omap_cf_driver); + return platform_driver_probe(&omap_cf_driver, omap_cf_probe); return -ENODEV; } static void __exit omap_cf_exit(void) { if (cpu_is_omap16xx()) - driver_unregister(&omap_cf_driver); + platform_driver_unregister(&omap_cf_driver); } module_init(omap_cf_init); diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 406bf61ed510..8890eba1db52 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -195,7 +195,7 @@ static struct dentry_operations fuse_dentry_operations = { .d_revalidate = fuse_dentry_revalidate, }; -static int valid_mode(int m) +int fuse_valid_type(int m) { return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) || S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m); @@ -248,7 +248,8 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, fuse_put_request(fc, req); /* Zero nodeid is same as -ENOENT, but with valid timeout */ if (!err && outarg.nodeid && - (invalid_nodeid(outarg.nodeid) || !valid_mode(outarg.attr.mode))) + (invalid_nodeid(outarg.nodeid) || + !fuse_valid_type(outarg.attr.mode))) err = -EIO; if (!err && outarg.nodeid) { inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index b98b20de7405..68ae87cbafab 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -552,3 +552,8 @@ int fuse_ctl_add_conn(struct fuse_conn *fc); * Remove connection from control filesystem */ void fuse_ctl_remove_conn(struct fuse_conn *fc); + +/** + * Is file type valid? + */ +int fuse_valid_type(int m); diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 5ab8e50e7808..608db81219a0 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -330,6 +330,8 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev) case OPT_ROOTMODE: if (match_octal(&args[0], &value)) return 0; + if (!fuse_valid_type(value)) + return 0; d->rootmode = value; d->rootmode_present = 1; break; diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index 00c23433b39f..6d7e279b1490 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h @@ -180,6 +180,7 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres #ifndef __HAVE_ARCH_ENTER_LAZY_MMU_MODE #define arch_enter_lazy_mmu_mode() do {} while (0) #define arch_leave_lazy_mmu_mode() do {} while (0) +#define arch_flush_lazy_mmu_mode() do {} while (0) #endif /* @@ -193,6 +194,7 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres #ifndef __HAVE_ARCH_ENTER_LAZY_CPU_MODE #define arch_enter_lazy_cpu_mode() do {} while (0) #define arch_leave_lazy_cpu_mode() do {} while (0) +#define arch_flush_lazy_cpu_mode() do {} while (0) #endif /* diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h index 46dc34ca887a..e63f1e444fcf 100644 --- a/include/asm-i386/paravirt.h +++ b/include/asm-i386/paravirt.h @@ -421,14 +421,17 @@ static inline void pmd_clear(pmd_t *pmdp) #define PARAVIRT_LAZY_NONE 0 #define PARAVIRT_LAZY_MMU 1 #define PARAVIRT_LAZY_CPU 2 +#define PARAVIRT_LAZY_FLUSH 3 #define __HAVE_ARCH_ENTER_LAZY_CPU_MODE #define arch_enter_lazy_cpu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_CPU) #define arch_leave_lazy_cpu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_NONE) +#define arch_flush_lazy_cpu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_FLUSH) #define __HAVE_ARCH_ENTER_LAZY_MMU_MODE #define arch_enter_lazy_mmu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_MMU) #define arch_leave_lazy_mmu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_NONE) +#define arch_flush_lazy_mmu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_FLUSH) /* These all sit in the .parainstructions section to tell us what to patch. */ struct paravirt_patch { diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 5bdbc744e773..17c29dca8354 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -206,6 +206,7 @@ struct hrtimer_cpu_base { struct clock_event_device; extern void clock_was_set(void); +extern void hres_timers_resume(void); extern void hrtimer_interrupt(struct clock_event_device *dev); /* @@ -236,6 +237,8 @@ static inline ktime_t hrtimer_cb_get_time(struct hrtimer *timer) */ static inline void clock_was_set(void) { } +static inline void hres_timers_resume(void) { } + /* * In non high resolution mode the time reference is taken from * the base softirq time variable. diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 067ba2c05328..b74860aaf5f1 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -459,6 +459,18 @@ void clock_was_set(void) } /* + * During resume we might have to reprogram the high resolution timer + * interrupt (on the local CPU): + */ +void hres_timers_resume(void) +{ + WARN_ON_ONCE(num_online_cpus() > 1); + + /* Retrigger the CPU local events: */ + retrigger_next_event(NULL); +} + +/* * Check, whether the timer is on the callback pending list */ static inline int hrtimer_cb_pending(const struct hrtimer *timer) diff --git a/kernel/irq/devres.c b/kernel/irq/devres.c index 85a430da0fb6..d8ee241115f5 100644 --- a/kernel/irq/devres.c +++ b/kernel/irq/devres.c @@ -54,7 +54,7 @@ int devm_request_irq(struct device *dev, unsigned int irq, rc = request_irq(irq, handler, irqflags, devname, dev_id); if (rc) { - kfree(dr); + devres_free(dr); return rc; } diff --git a/kernel/sched.c b/kernel/sched.c index a4ca632c477c..b9a683730148 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -4687,32 +4687,10 @@ out_unlock: return retval; } -static inline struct task_struct *eldest_child(struct task_struct *p) -{ - if (list_empty(&p->children)) - return NULL; - return list_entry(p->children.next,struct task_struct,sibling); -} - -static inline struct task_struct *older_sibling(struct task_struct *p) -{ - if (p->sibling.prev==&p->parent->children) - return NULL; - return list_entry(p->sibling.prev,struct task_struct,sibling); -} - -static inline struct task_struct *younger_sibling(struct task_struct *p) -{ - if (p->sibling.next==&p->parent->children) - return NULL; - return list_entry(p->sibling.next,struct task_struct,sibling); -} - static const char stat_nam[] = "RSDTtZX"; static void show_task(struct task_struct *p) { - struct task_struct *relative; unsigned long free = 0; unsigned state; @@ -4738,19 +4716,7 @@ static void show_task(struct task_struct *p) free = (unsigned long)n - (unsigned long)end_of_stack(p); } #endif - printk("%5lu %5d %6d ", free, p->pid, p->parent->pid); - if ((relative = eldest_child(p))) - printk("%5d ", relative->pid); - else - printk(" "); - if ((relative = younger_sibling(p))) - printk("%7d", relative->pid); - else - printk(" "); - if ((relative = older_sibling(p))) - printk(" %5d", relative->pid); - else - printk(" "); + printk("%5lu %5d %6d", free, p->pid, p->parent->pid); if (!p->mm) printk(" (L-TLB)\n"); else diff --git a/kernel/timer.c b/kernel/timer.c index 440048acaea1..dd6c2c1c561b 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -1016,7 +1016,7 @@ static int timekeeping_resume(struct sys_device *dev) clockevents_notify(CLOCK_EVT_NOTIFY_RESUME, NULL); /* Resume hrtimers */ - clock_was_set(); + hres_timers_resume(); return 0; } diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c index 89cf59ea7bbe..f68dfd8a0f5c 100644 --- a/net/ipv4/xfrm4_mode_beet.c +++ b/net/ipv4/xfrm4_mode_beet.c @@ -42,10 +42,9 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb) skb->nh.raw = skb_push(skb, x->props.header_len + hdrlen); top_iph = skb->nh.iph; - hdrlen = iph->ihl * 4 - optlen; - skb->h.raw += hdrlen; + skb->h.raw += sizeof(*iph) - hdrlen; - memmove(top_iph, iph, hdrlen); + memmove(top_iph, iph, sizeof(*iph)); if (unlikely(optlen)) { struct ip_beet_phdr *ph; @@ -55,6 +54,8 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb) ph->padlen = 4 - (optlen & 4); ph->hdrlen = (optlen + ph->padlen + sizeof(*ph)) / 8; ph->nexthdr = top_iph->protocol; + if (ph->padlen) + memset(ph + 1, IPOPT_NOP, ph->padlen); top_iph->protocol = IPPROTO_BEETPH; top_iph->ihl = sizeof(struct iphdr) / 4; @@ -77,29 +78,32 @@ static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb) protocol = iph->protocol; if (unlikely(iph->protocol == IPPROTO_BEETPH)) { - struct ip_beet_phdr *ph = (struct ip_beet_phdr*)(iph + 1); + struct ip_beet_phdr *ph; if (!pskb_may_pull(skb, sizeof(*ph))) goto out; + ph = (struct ip_beet_phdr *)(skb->h.ipiph + 1); - phlen = ph->hdrlen * 8; - optlen = phlen - ph->padlen - sizeof(*ph); + phlen = sizeof(*ph) + ph->padlen; + optlen = ph->hdrlen * 8 - phlen; if (optlen < 0 || optlen & 3 || optlen > 250) goto out; - if (!pskb_may_pull(skb, phlen)) + if (!pskb_may_pull(skb, phlen + optlen)) goto out; + skb->len -= phlen + optlen; ph_nexthdr = ph->nexthdr; } - skb_push(skb, sizeof(*iph) - phlen + optlen); - memmove(skb->data, skb->nh.raw, sizeof(*iph)); - skb->nh.raw = skb->data; + skb->nh.raw = skb->data + (phlen - sizeof(*iph)); + memmove(skb->nh.raw, iph, sizeof(*iph)); + skb->h.raw = skb->data + (phlen + optlen); + skb->data = skb->h.raw; iph = skb->nh.iph; iph->ihl = (sizeof(*iph) + optlen) / 4; - iph->tot_len = htons(skb->len); + iph->tot_len = htons(skb->len + iph->ihl * 4); iph->daddr = x->sel.daddr.a4; iph->saddr = x->sel.saddr.a4; if (ph_nexthdr) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 3931b33b25e8..ad9b285692ba 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -311,21 +311,12 @@ static inline void rt6_probe(struct rt6_info *rt) static inline int rt6_check_dev(struct rt6_info *rt, int oif) { struct net_device *dev = rt->rt6i_dev; - int ret = 0; - - if (!oif) - return 2; - if (dev->flags & IFF_LOOPBACK) { - if (!WARN_ON(rt->rt6i_idev == NULL) && - rt->rt6i_idev->dev->ifindex == oif) - ret = 1; - else - return 0; - } - if (dev->ifindex == oif) + if (!oif || dev->ifindex == oif) return 2; - - return ret; + if ((dev->flags & IFF_LOOPBACK) && + rt->rt6i_idev && rt->rt6i_idev->dev->ifindex == oif) + return 1; + return 0; } static inline int rt6_check_neigh(struct rt6_info *rt) |