Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 125488 Details for
Bug 184852
[2.6.21.2 regression] S3 ACPI wakeup from suspend broken
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
1001_linux-2.6.21.2.patch
1001_linux-2.6.21.2.patch (text/plain), 81.73 KB, created by
Maarten Bressers (RETIRED)
on 2007-07-20 19:57:09 UTC
(
hide
)
Description:
1001_linux-2.6.21.2.patch
Filename:
MIME Type:
Creator:
Maarten Bressers (RETIRED)
Created:
2007-07-20 19:57:09 UTC
Size:
81.73 KB
patch
obsolete
>diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c >index 2409560..7ed141f 100644 >--- a/arch/arm/kernel/traps.c >+++ b/arch/arm/kernel/traps.c >@@ -273,6 +273,7 @@ asmlinkage void do_undefinstr(struct pt_regs *regs) > struct undef_hook *hook; > siginfo_t info; > void __user *pc; >+ unsigned long flags; > > /* > * According to the ARM ARM, PC is 2 or 4 bytes ahead, >@@ -291,7 +292,7 @@ asmlinkage void do_undefinstr(struct pt_regs *regs) > get_user(instr, (u32 __user *)pc); > } > >- spin_lock_irq(&undef_lock); >+ spin_lock_irqsave(&undef_lock, flags); > list_for_each_entry(hook, &undef_hook, node) { > if ((instr & hook->instr_mask) == hook->instr_val && > (regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val) { >@@ -301,7 +302,7 @@ asmlinkage void do_undefinstr(struct pt_regs *regs) > } > } > } >- spin_unlock_irq(&undef_lock); >+ spin_unlock_irqrestore(&undef_lock, flags); > > #ifdef CONFIG_DEBUG_USER > if (user_debug & UDBG_UNDEFINED) { >diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c >index 89ec70e..d907a2a 100644 >--- a/arch/arm/mach-iop13xx/pci.c >+++ b/arch/arm/mach-iop13xx/pci.c >@@ -1023,7 +1023,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys) > << IOP13XX_ATUX_PCIXSR_FUNC_NUM; > __raw_writel(pcixsr, IOP13XX_ATUX_PCIXSR); > >- res[0].start = IOP13XX_PCIX_LOWER_IO_PA; >+ res[0].start = IOP13XX_PCIX_LOWER_IO_PA + IOP13XX_PCIX_IO_BUS_OFFSET; > res[0].end = IOP13XX_PCIX_UPPER_IO_PA; > res[0].name = "IQ81340 ATUX PCI I/O Space"; > res[0].flags = IORESOURCE_IO; >@@ -1033,7 +1033,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys) > res[1].name = "IQ81340 ATUX PCI Memory Space"; > res[1].flags = IORESOURCE_MEM; > sys->mem_offset = IOP13XX_PCIX_MEM_OFFSET; >- sys->io_offset = IOP13XX_PCIX_IO_OFFSET; >+ sys->io_offset = IOP13XX_PCIX_LOWER_IO_PA; > break; > case IOP13XX_INIT_ATU_ATUE: > /* Note: the function number field in the PCSR is ro */ >@@ -1044,7 +1044,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys) > > __raw_writel(pcsr, IOP13XX_ATUE_PCSR); > >- res[0].start = IOP13XX_PCIE_LOWER_IO_PA; >+ res[0].start = IOP13XX_PCIE_LOWER_IO_PA + IOP13XX_PCIE_IO_BUS_OFFSET; > res[0].end = IOP13XX_PCIE_UPPER_IO_PA; > res[0].name = "IQ81340 ATUE PCI I/O Space"; > res[0].flags = IORESOURCE_IO; >@@ -1054,7 +1054,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys) > res[1].name = "IQ81340 ATUE PCI Memory Space"; > res[1].flags = IORESOURCE_MEM; > sys->mem_offset = IOP13XX_PCIE_MEM_OFFSET; >- sys->io_offset = IOP13XX_PCIE_IO_OFFSET; >+ sys->io_offset = IOP13XX_PCIE_LOWER_IO_PA; > sys->map_irq = iop13xx_pcie_map_irq; > break; > default: >diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c >index 16300ad..0cc26da 100644 >--- a/arch/arm/plat-iop/time.c >+++ b/arch/arm/plat-iop/time.c >@@ -32,22 +32,22 @@ static unsigned long next_jiffy_time; > > unsigned long iop_gettimeoffset(void) > { >- unsigned long offset, temp1, temp2; >+ unsigned long offset, temp; > > /* enable cp6, if necessary, to avoid taking the overhead of an > * undefined instruction trap > */ > asm volatile ( > "mrc p15, 0, %0, c15, c1, 0\n\t" >- "ands %1, %0, #(1 << 6)\n\t" >+ "tst %0, #(1 << 6)\n\t" > "orreq %0, %0, #(1 << 6)\n\t" > "mcreq p15, 0, %0, c15, c1, 0\n\t" >-#ifdef CONFIG_XSCALE >+#ifdef CONFIG_CPU_XSCALE > "mrceq p15, 0, %0, c15, c1, 0\n\t" > "moveq %0, %0\n\t" > "subeq pc, pc, #4\n\t" > #endif >- : "=r"(temp1), "=r"(temp2) : : "cc"); >+ : "=r"(temp) : : "cc"); > > offset = next_jiffy_time - read_tcr1(); > >diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c >index 837b041..ca3e1d3 100644 >--- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c >+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c >@@ -341,15 +341,17 @@ static int powernow_acpi_init(void) > pc.val = (unsigned long) acpi_processor_perf->states[0].control; > for (i = 0; i < number_scales; i++) { > u8 fid, vid; >- unsigned int speed; >+ struct acpi_processor_px *state = >+ &acpi_processor_perf->states[i]; >+ unsigned int speed, speed_mhz; > >- pc.val = (unsigned long) acpi_processor_perf->states[i].control; >+ pc.val = (unsigned long) state->control; > dprintk ("acpi: P%d: %d MHz %d mW %d uS control %08x SGTC %d\n", > i, >- (u32) acpi_processor_perf->states[i].core_frequency, >- (u32) acpi_processor_perf->states[i].power, >- (u32) acpi_processor_perf->states[i].transition_latency, >- (u32) acpi_processor_perf->states[i].control, >+ (u32) state->core_frequency, >+ (u32) state->power, >+ (u32) state->transition_latency, >+ (u32) state->control, > pc.bits.sgtc); > > vid = pc.bits.vid; >@@ -360,6 +362,18 @@ static int powernow_acpi_init(void) > powernow_table[i].index |= (vid << 8); /* upper 8 bits */ > > speed = powernow_table[i].frequency; >+ speed_mhz = speed / 1000; >+ >+ /* processor_perflib will multiply the MHz value by 1000 to >+ * get a KHz value (e.g. 1266000). However, powernow-k7 works >+ * with true KHz values (e.g. 1266768). To ensure that all >+ * powernow frequencies are available, we must ensure that >+ * ACPI doesn't restrict them, so we round up the MHz value >+ * to ensure that perflib's computed KHz value is greater than >+ * or equal to powernow's KHz value. >+ */ >+ if (speed % 1000 > 0) >+ speed_mhz++; > > if ((fid_codes[fid] % 10)==5) { > if (have_a0 == 1) >@@ -368,10 +382,16 @@ static int powernow_acpi_init(void) > > dprintk (" FID: 0x%x (%d.%dx [%dMHz]) " > "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10, >- fid_codes[fid] % 10, speed/1000, vid, >+ fid_codes[fid] % 10, speed_mhz, vid, > mobile_vid_table[vid]/1000, > mobile_vid_table[vid]%1000); > >+ if (state->core_frequency != speed_mhz) { >+ state->core_frequency = speed_mhz; >+ dprintk(" Corrected ACPI frequency to %d\n", >+ speed_mhz); >+ } >+ > if (latency < pc.bits.sgtc) > latency = pc.bits.sgtc; > >@@ -602,7 +622,7 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy) > result = powernow_acpi_init(); > if (result) { > printk (KERN_INFO PFX "ACPI and legacy methods failed\n"); >- printk (KERN_INFO PFX "See http://www.codemonkey.org.uk/projects/cpufreq/powernow-k7.shtml\n"); >+ printk (KERN_INFO PFX "See http://www.codemonkey.org.uk/projects/cpufreq/powernow-k7.html\n"); > } > } else { > /* SGTC use the bus clock as timer */ >diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c >index fe3b670..e295d87 100644 >--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c >+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c >@@ -521,7 +521,7 @@ static int check_supported_cpu(unsigned int cpu) > > if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) { > if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || >- ((eax & CPUID_XMOD) > CPUID_XMOD_REV_G)) { >+ ((eax & CPUID_XMOD) > CPUID_XMOD_REV_MASK)) { > printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax); > goto out; > } >diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h >index 0fb2a30..575541f 100644 >--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h >+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h >@@ -46,8 +46,8 @@ struct powernow_k8_data { > #define CPUID_XFAM 0x0ff00000 /* extended family */ > #define CPUID_XFAM_K8 0 > #define CPUID_XMOD 0x000f0000 /* extended model */ >-#define CPUID_XMOD_REV_G 0x00060000 >-#define CPUID_XFAM_10H 0x00100000 /* family 0x10 */ >+#define CPUID_XMOD_REV_MASK 0x00080000 >+#define CPUID_XFAM_10H 0x00100000 /* family 0x10 */ > #define CPUID_USE_XFAM_XMOD 0x00000f00 > #define CPUID_GET_MAX_CAPABILITIES 0x80000000 > #define CPUID_FREQ_VOLT_CAPABILITIES 0x80000007 >diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c >index fb9bf1e..f56569f 100644 >--- a/arch/sparc64/kernel/of_device.c >+++ b/arch/sparc64/kernel/of_device.c >@@ -508,6 +508,13 @@ static int __init build_one_resource(struct device_node *parent, > return 0; > } > >+ /* When we miss an I/O space match on PCI, just pass it up >+ * to the next PCI bridge and/or controller. >+ */ >+ if (!strcmp(bus->name, "pci") && >+ (addr[0] & 0x03000000) == 0x01000000) >+ return 0; >+ > return 1; > } > >diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c >index 0917c24..3494adf 100644 >--- a/arch/sparc64/kernel/prom.c >+++ b/arch/sparc64/kernel/prom.c >@@ -1555,10 +1555,21 @@ static struct device_node * __init create_node(phandle node, struct device_node > > static struct device_node * __init build_tree(struct device_node *parent, phandle node, struct device_node ***nextp) > { >+ struct device_node *ret = NULL, *prev_sibling = NULL; > struct device_node *dp; > >- dp = create_node(node, parent); >- if (dp) { >+ while (1) { >+ dp = create_node(node, parent); >+ if (!dp) >+ break; >+ >+ if (prev_sibling) >+ prev_sibling->sibling = dp; >+ >+ if (!ret) >+ ret = dp; >+ prev_sibling = dp; >+ > *(*nextp) = dp; > *nextp = &dp->allnext; > >@@ -1567,10 +1578,10 @@ static struct device_node * __init build_tree(struct device_node *parent, phandl > > dp->child = build_tree(dp, prom_getchild(node), nextp); > >- dp->sibling = build_tree(parent, prom_getsibling(node), nextp); >+ node = prom_getsibling(node); > } > >- return dp; >+ return ret; > } > > void __init prom_build_devicetree(void) >diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c >index fc99f7b..8ad7bdb 100644 >--- a/arch/sparc64/kernel/smp.c >+++ b/arch/sparc64/kernel/smp.c >@@ -566,6 +566,9 @@ static void hypervisor_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t > unsigned long flags, status; > int cnt, retries, this_cpu, prev_sent, i; > >+ if (cpus_empty(mask)) >+ return; >+ > /* We have to do this whole thing with interrupts fully disabled. > * Otherwise if we send an xcall from interrupt context it will > * corrupt both our mondo block and cpu list state. >diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c >index b43c698..fc9f042 100644 >--- a/arch/x86_64/kernel/vsyscall.c >+++ b/arch/x86_64/kernel/vsyscall.c >@@ -132,7 +132,7 @@ static __always_inline void do_vgettimeofday(struct timeval * tv) > > /* convert to usecs and add to timespec: */ > tv->tv_usec += nsec_delta / NSEC_PER_USEC; >- while (tv->tv_usec > USEC_PER_SEC) { >+ while (tv->tv_usec >= USEC_PER_SEC) { > tv->tv_sec += 1; > tv->tv_usec -= USEC_PER_SEC; > } >diff --git a/crypto/api.c b/crypto/api.c >index 55af8bb..33734fd 100644 >--- a/crypto/api.c >+++ b/crypto/api.c >@@ -48,8 +48,10 @@ EXPORT_SYMBOL_GPL(crypto_mod_get); > > void crypto_mod_put(struct crypto_alg *alg) > { >+ struct module *module = alg->cra_module; >+ > crypto_alg_put(alg); >- module_put(alg->cra_module); >+ module_put(module); > } > EXPORT_SYMBOL_GPL(crypto_mod_put); > >diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c >index 807c711..d341491 100644 >--- a/drivers/acpi/tables/tbfadt.c >+++ b/drivers/acpi/tables/tbfadt.c >@@ -347,6 +347,20 @@ static void acpi_tb_convert_fadt(void) > acpi_gbl_xpm1b_enable.space_id = acpi_gbl_FADT.xpm1a_event_block.space_id; > > } >+ /* >+ * _CST object and C States change notification start with >+ * ACPI 2.0 (FADT r3). Although the field should be Reserved >+ * and 0 before then, some pre-r3 FADT set this field and >+ * it results in SMM-related boot failures. For them, clear it. >+ */ >+ if ((acpi_gbl_FADT.header.revision < 3) && >+ (acpi_gbl_FADT.cst_control != 0)) { >+ ACPI_WARNING((AE_INFO, >+ "Ignoring BIOS FADT r%u C-state control", >+ acpi_gbl_FADT.header.revision)); >+ acpi_gbl_FADT.cst_control = 0; >+ } >+ > } > > /****************************************************************************** >diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c >index 2ffcca0..4d63974 100644 >--- a/drivers/ata/libata-sff.c >+++ b/drivers/ata/libata-sff.c >@@ -557,12 +557,30 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int > int i, p = 0; > void __iomem * const *iomap; > >+ /* Discard disabled ports. Some controllers show their >+ unused channels this way */ >+ if (ata_resources_present(pdev, 0) == 0) >+ ports &= ~ATA_PORT_PRIMARY; >+ if (ata_resources_present(pdev, 1) == 0) >+ ports &= ~ATA_PORT_SECONDARY; >+ > /* iomap BARs */ >- for (i = 0; i < 4; i++) { >- if (pcim_iomap(pdev, i, 0) == NULL) { >- dev_printk(KERN_ERR, &pdev->dev, >- "failed to iomap PCI BAR %d\n", i); >- return NULL; >+ if (ports & ATA_PORT_PRIMARY) { >+ for (i = 0; i <= 1; i++) { >+ if (pcim_iomap(pdev, i, 0) == NULL) { >+ dev_printk(KERN_ERR, &pdev->dev, >+ "failed to iomap PCI BAR %d\n", i); >+ return NULL; >+ } >+ } >+ } >+ if (ports & ATA_PORT_SECONDARY) { >+ for (i = 2; i <= 3; i++) { >+ if (pcim_iomap(pdev, i, 0) == NULL) { >+ dev_printk(KERN_ERR, &pdev->dev, >+ "failed to iomap PCI BAR %d\n", i); >+ return NULL; >+ } > } > } > >@@ -577,13 +595,6 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int > probe_ent->irq = pdev->irq; > probe_ent->irq_flags = IRQF_SHARED; > >- /* Discard disabled ports. Some controllers show their >- unused channels this way */ >- if (ata_resources_present(pdev, 0) == 0) >- ports &= ~ATA_PORT_PRIMARY; >- if (ata_resources_present(pdev, 1) == 0) >- ports &= ~ATA_PORT_SECONDARY; >- > if (ports & ATA_PORT_PRIMARY) { > probe_ent->port[p].cmd_addr = iomap[0]; > probe_ent->port[p].altstatus_addr = >diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c >index 598e6a2..ea6efca 100644 >--- a/drivers/ata/sata_via.c >+++ b/drivers/ata/sata_via.c >@@ -97,6 +97,10 @@ static struct pci_driver svia_pci_driver = { > .name = DRV_NAME, > .id_table = svia_pci_tbl, > .probe = svia_init_one, >+#ifdef CONFIG_PM >+ .suspend = ata_pci_device_suspend, >+ .resume = ata_pci_device_resume, >+#endif > .remove = ata_pci_remove_one, > }; > >@@ -116,6 +120,10 @@ static struct scsi_host_template svia_sht = { > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >+#ifdef CONFIG_PM >+ .suspend = ata_scsi_device_suspend, >+ .resume = ata_scsi_device_resume, >+#endif > }; > > static const struct ata_port_operations vt6420_sata_ops = { >diff --git a/drivers/base/core.c b/drivers/base/core.c >index d7fcf82..a8dfee2 100644 >--- a/drivers/base/core.c >+++ b/drivers/base/core.c >@@ -93,6 +93,9 @@ static void device_release(struct kobject * kobj) > { > struct device * dev = to_dev(kobj); > >+ kfree(dev->devt_attr); >+ dev->devt_attr = NULL; >+ > if (dev->release) > dev->release(dev); > else if (dev->type && dev->type->release) >@@ -765,10 +768,8 @@ void device_del(struct device * dev) > > if (parent) > klist_del(&dev->knode_parent); >- if (dev->devt_attr) { >+ if (dev->devt_attr) > device_remove_file(dev, dev->devt_attr); >- kfree(dev->devt_attr); >- } > if (dev->class) { > sysfs_remove_link(&dev->kobj, "subsystem"); > /* If this is not a "fake" compatible device, remove the >diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c >index e221465..cc13ebc 100644 >--- a/drivers/char/ipmi/ipmi_si_intf.c >+++ b/drivers/char/ipmi/ipmi_si_intf.c >@@ -1859,10 +1859,10 @@ static __devinit int try_init_acpi(struct SPMITable *spmi) > > if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { > info->io_setup = mem_setup; >- info->io.addr_type = IPMI_IO_ADDR_SPACE; >+ info->io.addr_type = IPMI_MEM_ADDR_SPACE; > } else if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_IO) { > info->io_setup = port_setup; >- info->io.addr_type = IPMI_MEM_ADDR_SPACE; >+ info->io.addr_type = IPMI_IO_ADDR_SPACE; > } else { > kfree(info); > printk("ipmi_si: Unknown ACPI I/O Address type\n"); >diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c >index 97ee870..3a95cc5 100644 >--- a/drivers/md/raid1.c >+++ b/drivers/md/raid1.c >@@ -271,21 +271,25 @@ static int raid1_end_read_request(struct bio *bio, unsigned int bytes_done, int > */ > update_head_pos(mirror, r1_bio); > >- if (uptodate || (conf->raid_disks - conf->mddev->degraded) <= 1) { >- /* >- * Set R1BIO_Uptodate in our master bio, so that >- * we will return a good error code for to the higher >- * levels even if IO on some other mirrored buffer fails. >- * >- * The 'master' represents the composite IO operation to >- * user-side. So if something waits for IO, then it will >- * wait for the 'master' bio. >+ if (uptodate) >+ set_bit(R1BIO_Uptodate, &r1_bio->state); >+ else { >+ /* If all other devices have failed, we want to return >+ * the error upwards rather than fail the last device. >+ * Here we redefine "uptodate" to mean "Don't want to retry" > */ >- if (uptodate) >- set_bit(R1BIO_Uptodate, &r1_bio->state); >+ unsigned long flags; >+ spin_lock_irqsave(&conf->device_lock, flags); >+ if (r1_bio->mddev->degraded == conf->raid_disks || >+ (r1_bio->mddev->degraded == conf->raid_disks-1 && >+ !test_bit(Faulty, &conf->mirrors[mirror].rdev->flags))) >+ uptodate = 1; >+ spin_unlock_irqrestore(&conf->device_lock, flags); >+ } > >+ if (uptodate) > raid_end_bio_io(r1_bio); >- } else { >+ else { > /* > * oops, read error: > */ >@@ -992,13 +996,14 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) > unsigned long flags; > spin_lock_irqsave(&conf->device_lock, flags); > mddev->degraded++; >+ set_bit(Faulty, &rdev->flags); > spin_unlock_irqrestore(&conf->device_lock, flags); > /* > * if recovery is running, make sure it aborts. > */ > set_bit(MD_RECOVERY_ERR, &mddev->recovery); >- } >- set_bit(Faulty, &rdev->flags); >+ } else >+ set_bit(Faulty, &rdev->flags); > set_bit(MD_CHANGE_DEVS, &mddev->flags); > printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n" > " Operation continuing on %d devices\n", >diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c >index 85f21b5..2eb5741 100644 >--- a/drivers/message/fusion/mptspi.c >+++ b/drivers/message/fusion/mptspi.c >@@ -726,13 +726,15 @@ static int mptspi_slave_configure(struct scsi_device *sdev) > struct _MPT_SCSI_HOST *hd = > (struct _MPT_SCSI_HOST *)sdev->host->hostdata; > VirtTarget *vtarget = scsi_target(sdev)->hostdata; >- int ret = mptscsih_slave_configure(sdev); >+ int ret; >+ >+ mptspi_initTarget(hd, vtarget, sdev); >+ >+ ret = mptscsih_slave_configure(sdev); > > if (ret) > return ret; > >- mptspi_initTarget(hd, vtarget, sdev); >- > ddvprintk((MYIOC_s_INFO_FMT "id=%d min_period=0x%02x" > " max_offset=0x%02x max_width=%d\n", hd->ioc->name, > sdev->id, spi_min_period(scsi_target(sdev)), >diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig >index a3d46ea..32a3003 100644 >--- a/drivers/net/Kconfig >+++ b/drivers/net/Kconfig >@@ -2929,11 +2929,6 @@ endif #NETDEVICES > config NETPOLL > def_bool NETCONSOLE > >-config NETPOLL_RX >- bool "Netpoll support for trapping incoming packets" >- default n >- depends on NETPOLL >- > config NETPOLL_TRAP > bool "Netpoll traffic trapping" > default n >diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c >index e85f5ec..5006c67 100644 >--- a/drivers/net/bnx2.c >+++ b/drivers/net/bnx2.c >@@ -54,8 +54,8 @@ > > #define DRV_MODULE_NAME "bnx2" > #define PFX DRV_MODULE_NAME ": " >-#define DRV_MODULE_VERSION "1.5.8" >-#define DRV_MODULE_RELDATE "April 24, 2007" >+#define DRV_MODULE_VERSION "1.5.8.1" >+#define DRV_MODULE_RELDATE "May 7, 2007" > > #define RUN_AT(x) (jiffies + (x)) > >@@ -4510,8 +4510,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) > vlan_tag_flags |= > (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16)); > } >- if ((mss = skb_shinfo(skb)->gso_size) && >- (skb->len > (bp->dev->mtu + ETH_HLEN))) { >+ if ((mss = skb_shinfo(skb)->gso_size)) { > u32 tcp_opt_len, ip_tcp_len; > > if (skb_header_cloned(skb) && >@@ -5565,6 +5564,9 @@ bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) > case SIOCGMIIREG: { > u32 mii_regval; > >+ if (!netif_running(dev)) >+ return -EAGAIN; >+ > spin_lock_bh(&bp->phy_lock); > err = bnx2_read_phy(bp, data->reg_num & 0x1f, &mii_regval); > spin_unlock_bh(&bp->phy_lock); >@@ -5578,6 +5580,9 @@ bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) > if (!capable(CAP_NET_ADMIN)) > return -EPERM; > >+ if (!netif_running(dev)) >+ return -EAGAIN; >+ > spin_lock_bh(&bp->phy_lock); > err = bnx2_write_phy(bp, data->reg_num & 0x1f, data->val_in); > spin_unlock_bh(&bp->phy_lock); >@@ -6143,6 +6148,7 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state) > reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL; > bnx2_reset_chip(bp, reset_code); > bnx2_free_skbs(bp); >+ pci_save_state(pdev); > bnx2_set_power_state(bp, pci_choose_state(pdev, state)); > return 0; > } >@@ -6156,6 +6162,7 @@ bnx2_resume(struct pci_dev *pdev) > if (!netif_running(dev)) > return 0; > >+ pci_restore_state(pdev); > bnx2_set_power_state(bp, PCI_D0); > netif_device_attach(dev); > bnx2_init_nic(bp); >diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c >index b2a3b19..ce547af 100644 >--- a/drivers/net/sis900.c >+++ b/drivers/net/sis900.c >@@ -1754,6 +1754,7 @@ static int sis900_rx(struct net_device *net_dev) > sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE; > } else { > struct sk_buff * skb; >+ struct sk_buff * rx_skb; > > pci_unmap_single(sis_priv->pci_dev, > sis_priv->rx_ring[entry].bufptr, RX_BUF_SIZE, >@@ -1787,10 +1788,10 @@ static int sis900_rx(struct net_device *net_dev) > } > > /* give the socket buffer to upper layers */ >- skb = sis_priv->rx_skbuff[entry]; >- skb_put(skb, rx_size); >- skb->protocol = eth_type_trans(skb, net_dev); >- netif_rx(skb); >+ rx_skb = sis_priv->rx_skbuff[entry]; >+ skb_put(rx_skb, rx_size); >+ rx_skb->protocol = eth_type_trans(rx_skb, net_dev); >+ netif_rx(rx_skb); > > /* some network statistics */ > if ((rx_status & BCAST) == MCAST) >diff --git a/drivers/net/skge.c b/drivers/net/skge.c >index d476a3c..5ef9023 100644 >--- a/drivers/net/skge.c >+++ b/drivers/net/skge.c >@@ -135,10 +135,13 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs, > /* Wake on Lan only supported on Yukon chips with rev 1 or above */ > static u32 wol_supported(const struct skge_hw *hw) > { >- if (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev != 0) >- return WAKE_MAGIC | WAKE_PHY; >- else >+ if (hw->chip_id == CHIP_ID_GENESIS) >+ return 0; >+ >+ if (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0) > return 0; >+ >+ return WAKE_MAGIC | WAKE_PHY; > } > > static u32 pci_wake_enabled(struct pci_dev *dev) >@@ -3583,7 +3586,9 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, > skge->duplex = -1; > skge->speed = -1; > skge->advertising = skge_supported_modes(hw); >- skge->wol = pci_wake_enabled(hw->pdev) ? wol_supported(hw) : 0; >+ >+ if (pci_wake_enabled(hw->pdev)) >+ skge->wol = wol_supported(hw) & WAKE_MAGIC; > > hw->dev[port] = dev; > >@@ -3789,6 +3794,9 @@ static int skge_suspend(struct pci_dev *pdev, pm_message_t state) > struct skge_hw *hw = pci_get_drvdata(pdev); > int i, err, wol = 0; > >+ if (!hw) >+ return 0; >+ > err = pci_save_state(pdev); > if (err) > return err; >@@ -3817,6 +3825,9 @@ static int skge_resume(struct pci_dev *pdev) > struct skge_hw *hw = pci_get_drvdata(pdev); > int i, err; > >+ if (!hw) >+ return 0; >+ > err = pci_set_power_state(pdev, PCI_D0); > if (err) > goto out; >@@ -3855,6 +3866,9 @@ static void skge_shutdown(struct pci_dev *pdev) > struct skge_hw *hw = pci_get_drvdata(pdev); > int i, wol = 0; > >+ if (!hw) >+ return; >+ > for (i = 0; i < hw->ports; i++) { > struct net_device *dev = hw->dev[i]; > struct skge_port *skge = netdev_priv(dev); >diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c >index ac36152..b6b444b 100644 >--- a/drivers/net/sky2.c >+++ b/drivers/net/sky2.c >@@ -123,16 +123,13 @@ static const struct pci_device_id sky2_id_table[] = { > { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */ > { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, /* 88E8053 */ > { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, /* 88E8055 */ >-#ifdef broken >- /* This device causes data corruption problems that are not resolved */ > { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) }, /* 88E8056 */ >-#endif > { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, /* 88EC036 */ > { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, /* 88EC032 */ > { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */ > { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) }, /* 88EC042 */ > { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436A) }, /* 88E8058 */ >- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */ >+// { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */ > { 0 } > }; > >@@ -3722,6 +3719,7 @@ err_out_free_regions: > pci_release_regions(pdev); > pci_disable_device(pdev); > err_out: >+ pci_set_drvdata(pdev, NULL); > return err; > } > >@@ -3774,6 +3772,9 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) > struct sky2_hw *hw = pci_get_drvdata(pdev); > int i, wol = 0; > >+ if (!hw) >+ return 0; >+ > del_timer_sync(&hw->idle_timer); > netif_poll_disable(hw->dev[0]); > >@@ -3805,6 +3806,9 @@ static int sky2_resume(struct pci_dev *pdev) > struct sky2_hw *hw = pci_get_drvdata(pdev); > int i, err; > >+ if (!hw) >+ return 0; >+ > err = pci_set_power_state(pdev, PCI_D0); > if (err) > goto out; >@@ -3851,6 +3855,9 @@ static void sky2_shutdown(struct pci_dev *pdev) > struct sky2_hw *hw = pci_get_drvdata(pdev); > int i, wol = 0; > >+ if (!hw) >+ return; >+ > del_timer_sync(&hw->idle_timer); > netif_poll_disable(hw->dev[0]); > >diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c >index c956141..0b89812 100644 >--- a/drivers/net/smc911x.c >+++ b/drivers/net/smc911x.c >@@ -499,7 +499,7 @@ static inline void smc911x_rcv(struct net_device *dev) > SMC_SET_RX_CFG(RX_CFG_RX_END_ALGN4_ | ((2<<8) & RX_CFG_RXDOFF_)); > SMC_PULL_DATA(data, pkt_len+2+3); > >- DBG(SMC_DEBUG_PKTS, "%s: Received packet\n", dev->name,); >+ DBG(SMC_DEBUG_PKTS, "%s: Received packet\n", dev->name); > PRINT_PKT(data, ((pkt_len - 4) <= 64) ? pkt_len - 4 : 64); > dev->last_rx = jiffies; > skb->dev = dev; >diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c >index 256969e..3d20115 100644 >--- a/drivers/net/tg3.c >+++ b/drivers/net/tg3.c >@@ -64,8 +64,8 @@ > > #define DRV_MODULE_NAME "tg3" > #define PFX DRV_MODULE_NAME ": " >-#define DRV_MODULE_VERSION "3.75" >-#define DRV_MODULE_RELDATE "March 23, 2007" >+#define DRV_MODULE_VERSION "3.75.1" >+#define DRV_MODULE_RELDATE "May 7, 2007" > > #define TG3_DEF_MAC_MODE 0 > #define TG3_DEF_RX_MODE 0 >@@ -3895,8 +3895,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) > entry = tp->tx_prod; > base_flags = 0; > mss = 0; >- if (skb->len > (tp->dev->mtu + ETH_HLEN) && >- (mss = skb_shinfo(skb)->gso_size) != 0) { >+ if ((mss = skb_shinfo(skb)->gso_size) != 0) { > int tcp_opt_len, ip_tcp_len; > > if (skb_header_cloned(skb) && >@@ -4053,8 +4052,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) > if (skb->ip_summed == CHECKSUM_PARTIAL) > base_flags |= TXD_FLAG_TCPUDP_CSUM; > mss = 0; >- if (skb->len > (tp->dev->mtu + ETH_HLEN) && >- (mss = skb_shinfo(skb)->gso_size) != 0) { >+ if ((mss = skb_shinfo(skb)->gso_size) != 0) { > int tcp_opt_len, ip_tcp_len, hdr_len; > > if (skb_header_cloned(skb) && >@@ -5936,7 +5934,7 @@ static int tg3_load_tso_firmware(struct tg3 *tp) > > > /* tp->lock is held. */ >-static void __tg3_set_mac_addr(struct tg3 *tp) >+static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1) > { > u32 addr_high, addr_low; > int i; >@@ -5948,6 +5946,8 @@ static void __tg3_set_mac_addr(struct tg3 *tp) > (tp->dev->dev_addr[4] << 8) | > (tp->dev->dev_addr[5] << 0)); > for (i = 0; i < 4; i++) { >+ if (i == 1 && skip_mac_1) >+ continue; > tw32(MAC_ADDR_0_HIGH + (i * 8), addr_high); > tw32(MAC_ADDR_0_LOW + (i * 8), addr_low); > } >@@ -5974,7 +5974,7 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p) > { > struct tg3 *tp = netdev_priv(dev); > struct sockaddr *addr = p; >- int err = 0; >+ int err = 0, skip_mac_1 = 0; > > if (!is_valid_ether_addr(addr->sa_data)) > return -EINVAL; >@@ -5985,22 +5985,21 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p) > return 0; > > if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { >- /* Reset chip so that ASF can re-init any MAC addresses it >- * needs. >- */ >- tg3_netif_stop(tp); >- tg3_full_lock(tp, 1); >+ u32 addr0_high, addr0_low, addr1_high, addr1_low; > >- tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); >- err = tg3_restart_hw(tp, 0); >- if (!err) >- tg3_netif_start(tp); >- tg3_full_unlock(tp); >- } else { >- spin_lock_bh(&tp->lock); >- __tg3_set_mac_addr(tp); >- spin_unlock_bh(&tp->lock); >+ addr0_high = tr32(MAC_ADDR_0_HIGH); >+ addr0_low = tr32(MAC_ADDR_0_LOW); >+ addr1_high = tr32(MAC_ADDR_1_HIGH); >+ addr1_low = tr32(MAC_ADDR_1_LOW); >+ >+ /* Skip MAC addr 1 if ASF is using it. */ >+ if ((addr0_high != addr1_high || addr0_low != addr1_low) && >+ !(addr1_high == 0 && addr1_low == 0)) >+ skip_mac_1 = 1; > } >+ spin_lock_bh(&tp->lock); >+ __tg3_set_mac_addr(tp, skip_mac_1); >+ spin_unlock_bh(&tp->lock); > > return err; > } >@@ -6317,7 +6316,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) > tp->rx_jumbo_ptr); > > /* Initialize MAC address and backoff seed. */ >- __tg3_set_mac_addr(tp); >+ __tg3_set_mac_addr(tp, 0); > > /* MTU + ethernet header + FCS + optional VLAN tag */ > tw32(MAC_RX_MTU_SIZE, tp->dev->mtu + ETH_HLEN + 8); >@@ -6348,8 +6347,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) > tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) || > (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)) { > if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE && >- (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 || >- tp->pci_chip_rev_id == CHIPREV_ID_5705_A2)) { >+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { > rdmac_mode |= RDMAC_MODE_FIFO_SIZE_128; > } else if (!(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH) && > !(tp->tg3_flags2 & TG3_FLG2_IS_5788)) { >diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c >index 65d6f23..5af9125 100644 >--- a/drivers/pci/quirks.c >+++ b/drivers/pci/quirks.c >@@ -1737,18 +1737,20 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, > quirk_nvidia_ck804_pcie_aer_ext_cap); > > #ifdef CONFIG_PCI_MSI >-/* The Serverworks PCI-X chipset does not support MSI. We cannot easily rely >- * on setting PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually >- * some other busses controlled by the chipset even if Linux is not aware of it. >- * Instead of setting the flag on all busses in the machine, simply disable MSI >- * globally. >+/* Some chipsets do not support MSI. We cannot easily rely on setting >+ * PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually >+ * some other busses controlled by the chipset even if Linux is not >+ * aware of it. Instead of setting the flag on all busses in the >+ * machine, simply disable MSI globally. > */ >-static void __init quirk_svw_msi(struct pci_dev *dev) >+static void __init quirk_disable_all_msi(struct pci_dev *dev) > { > pci_no_msi(); > printk(KERN_WARNING "PCI: MSI quirk detected. MSI deactivated.\n"); > } >-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_svw_msi); >+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_disable_all_msi); >+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi); >+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_all_msi); > > /* Disable MSI on chipsets that are known to not support it */ > static void __devinit quirk_disable_msi(struct pci_dev *dev) >diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c >index 40d4856..c3a6bd2 100644 >--- a/drivers/serial/sunhv.c >+++ b/drivers/serial/sunhv.c >@@ -493,6 +493,10 @@ static struct of_device_id hv_match[] = { > .name = "console", > .compatible = "qcn", > }, >+ { >+ .name = "console", >+ .compatible = "SUNW,sun4v-console", >+ }, > {}, > }; > MODULE_DEVICE_TABLE(of, hv_match); >diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c >index 3dfa3e4..3257d94 100644 >--- a/drivers/usb/atm/cxacru.c >+++ b/drivers/usb/atm/cxacru.c >@@ -146,6 +146,12 @@ enum cxacru_info_idx { > CXINF_MAX = 0x1c, > }; > >+enum poll_state { >+ CX_INIT, >+ CX_POLLING, >+ CX_ABORT >+}; >+ > struct cxacru_modem_type { > u32 pll_f_clk; > u32 pll_b_clk; >@@ -159,6 +165,8 @@ struct cxacru_data { > > int line_status; > struct delayed_work poll_work; >+ struct mutex poll_state_serialize; >+ enum poll_state poll_state; > > /* contol handles */ > struct mutex cm_serialize; >@@ -356,7 +364,7 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance, > /* > struct atm_dev *atm_dev = usbatm_instance->atm_dev; > */ >- int ret; >+ int ret, start_polling = 1; > > dbg("cxacru_atm_start"); > >@@ -376,7 +384,15 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance, > } > > /* Start status polling */ >- cxacru_poll_status(&instance->poll_work.work); >+ mutex_lock(&instance->poll_state_serialize); >+ if (instance->poll_state == CX_INIT) >+ instance->poll_state = CX_POLLING; >+ else /* poll_state == CX_ABORT */ >+ start_polling = 0; >+ mutex_unlock(&instance->poll_state_serialize); >+ >+ if (start_polling) >+ cxacru_poll_status(&instance->poll_work.work); > return 0; > } > >@@ -685,6 +701,9 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, > instance->usbatm = usbatm_instance; > instance->modem_type = (struct cxacru_modem_type *) id->driver_info; > >+ mutex_init(&instance->poll_state_serialize); >+ instance->poll_state = CX_INIT; >+ > instance->rcv_buf = (u8 *) __get_free_page(GFP_KERNEL); > if (!instance->rcv_buf) { > dbg("cxacru_bind: no memory for rcv_buf"); >@@ -744,6 +763,7 @@ static void cxacru_unbind(struct usbatm_data *usbatm_instance, > struct usb_interface *intf) > { > struct cxacru_data *instance = usbatm_instance->driver_data; >+ int stop_polling = 1; > > dbg("cxacru_unbind entered"); > >@@ -752,8 +772,20 @@ static void cxacru_unbind(struct usbatm_data *usbatm_instance, > return; > } > >- while (!cancel_delayed_work(&instance->poll_work)) >- flush_scheduled_work(); >+ mutex_lock(&instance->poll_state_serialize); >+ if (instance->poll_state != CX_POLLING) { >+ /* Polling hasn't started yet and with >+ * the mutex locked it can be prevented >+ * from starting. >+ */ >+ instance->poll_state = CX_ABORT; >+ stop_polling = 0; >+ } >+ mutex_unlock(&instance->poll_state_serialize); >+ >+ if (stop_polling) >+ while (!cancel_delayed_work(&instance->poll_work)) >+ flush_scheduled_work(); > > usb_kill_urb(instance->snd_urb); > usb_kill_urb(instance->rcv_urb); >diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c >index a8b3d66..488d61b 100644 >--- a/drivers/usb/input/hiddev.c >+++ b/drivers/usb/input/hiddev.c >@@ -51,6 +51,7 @@ struct hiddev { > wait_queue_head_t wait; > struct hid_device *hid; > struct list_head list; >+ spinlock_t list_lock; > }; > > struct hiddev_list { >@@ -161,7 +162,9 @@ static void hiddev_send_event(struct hid_device *hid, > { > struct hiddev *hiddev = hid->hiddev; > struct hiddev_list *list; >+ unsigned long flags; > >+ spin_lock_irqsave(&hiddev->list_lock, flags); > list_for_each_entry(list, &hiddev->list, node) { > if (uref->field_index != HID_FIELD_INDEX_NONE || > (list->flags & HIDDEV_FLAG_REPORT) != 0) { >@@ -171,6 +174,7 @@ static void hiddev_send_event(struct hid_device *hid, > kill_fasync(&list->fasync, SIGIO, POLL_IN); > } > } >+ spin_unlock_irqrestore(&hiddev->list_lock, flags); > > wake_up_interruptible(&hiddev->wait); > } >@@ -235,9 +239,13 @@ static int hiddev_fasync(int fd, struct file *file, int on) > static int hiddev_release(struct inode * inode, struct file * file) > { > struct hiddev_list *list = file->private_data; >+ unsigned long flags; > > hiddev_fasync(-1, file, 0); >+ >+ spin_lock_irqsave(&list->hiddev->list_lock, flags); > list_del(&list->node); >+ spin_unlock_irqrestore(&list->hiddev->list_lock, flags); > > if (!--list->hiddev->open) { > if (list->hiddev->exist) >@@ -257,6 +265,7 @@ static int hiddev_release(struct inode * inode, struct file * file) > static int hiddev_open(struct inode *inode, struct file *file) > { > struct hiddev_list *list; >+ unsigned long flags; > > int i = iminor(inode) - HIDDEV_MINOR_BASE; > >@@ -267,7 +276,11 @@ static int hiddev_open(struct inode *inode, struct file *file) > return -ENOMEM; > > list->hiddev = hiddev_table[i]; >+ >+ spin_lock_irqsave(&list->hiddev->list_lock, flags); > list_add_tail(&list->node, &hiddev_table[i]->list); >+ spin_unlock_irqrestore(&list->hiddev->list_lock, flags); >+ > file->private_data = list; > > if (!list->hiddev->open++) >@@ -773,6 +786,7 @@ int hiddev_connect(struct hid_device *hid) > > init_waitqueue_head(&hiddev->wait); > INIT_LIST_HEAD(&hiddev->list); >+ spin_lock_init(&hiddev->list_lock); > hiddev->hid = hid; > hiddev->exist = 1; > >diff --git a/fs/fat/dir.c b/fs/fat/dir.c >index c16af24..ccf161d 100644 >--- a/fs/fat/dir.c >+++ b/fs/fat/dir.c >@@ -422,7 +422,7 @@ EODir: > EXPORT_SYMBOL_GPL(fat_search_long); > > struct fat_ioctl_filldir_callback { >- struct dirent __user *dirent; >+ void __user *dirent; > int result; > /* for dir ioctl */ > const char *longname; >@@ -647,62 +647,85 @@ static int fat_readdir(struct file *filp, void *dirent, filldir_t filldir) > return __fat_readdir(inode, filp, dirent, filldir, 0, 0); > } > >-static int fat_ioctl_filldir(void *__buf, const char *name, int name_len, >- loff_t offset, u64 ino, unsigned int d_type) >+#define FAT_IOCTL_FILLDIR_FUNC(func, dirent_type) \ >+static int func(void *__buf, const char *name, int name_len, \ >+ loff_t offset, u64 ino, unsigned int d_type) \ >+{ \ >+ struct fat_ioctl_filldir_callback *buf = __buf; \ >+ struct dirent_type __user *d1 = buf->dirent; \ >+ struct dirent_type __user *d2 = d1 + 1; \ >+ \ >+ if (buf->result) \ >+ return -EINVAL; \ >+ buf->result++; \ >+ \ >+ if (name != NULL) { \ >+ /* dirent has only short name */ \ >+ if (name_len >= sizeof(d1->d_name)) \ >+ name_len = sizeof(d1->d_name) - 1; \ >+ \ >+ if (put_user(0, d2->d_name) || \ >+ put_user(0, &d2->d_reclen) || \ >+ copy_to_user(d1->d_name, name, name_len) || \ >+ put_user(0, d1->d_name + name_len) || \ >+ put_user(name_len, &d1->d_reclen)) \ >+ goto efault; \ >+ } else { \ >+ /* dirent has short and long name */ \ >+ const char *longname = buf->longname; \ >+ int long_len = buf->long_len; \ >+ const char *shortname = buf->shortname; \ >+ int short_len = buf->short_len; \ >+ \ >+ if (long_len >= sizeof(d1->d_name)) \ >+ long_len = sizeof(d1->d_name) - 1; \ >+ if (short_len >= sizeof(d1->d_name)) \ >+ short_len = sizeof(d1->d_name) - 1; \ >+ \ >+ if (copy_to_user(d2->d_name, longname, long_len) || \ >+ put_user(0, d2->d_name + long_len) || \ >+ put_user(long_len, &d2->d_reclen) || \ >+ put_user(ino, &d2->d_ino) || \ >+ put_user(offset, &d2->d_off) || \ >+ copy_to_user(d1->d_name, shortname, short_len) || \ >+ put_user(0, d1->d_name + short_len) || \ >+ put_user(short_len, &d1->d_reclen)) \ >+ goto efault; \ >+ } \ >+ return 0; \ >+efault: \ >+ buf->result = -EFAULT; \ >+ return -EFAULT; \ >+} >+ >+FAT_IOCTL_FILLDIR_FUNC(fat_ioctl_filldir, dirent) >+ >+static int fat_ioctl_readdir(struct inode *inode, struct file *filp, >+ void __user *dirent, filldir_t filldir, >+ int short_only, int both) > { >- struct fat_ioctl_filldir_callback *buf = __buf; >- struct dirent __user *d1 = buf->dirent; >- struct dirent __user *d2 = d1 + 1; >- >- if (buf->result) >- return -EINVAL; >- buf->result++; >- >- if (name != NULL) { >- /* dirent has only short name */ >- if (name_len >= sizeof(d1->d_name)) >- name_len = sizeof(d1->d_name) - 1; >- >- if (put_user(0, d2->d_name) || >- put_user(0, &d2->d_reclen) || >- copy_to_user(d1->d_name, name, name_len) || >- put_user(0, d1->d_name + name_len) || >- put_user(name_len, &d1->d_reclen)) >- goto efault; >- } else { >- /* dirent has short and long name */ >- const char *longname = buf->longname; >- int long_len = buf->long_len; >- const char *shortname = buf->shortname; >- int short_len = buf->short_len; >- >- if (long_len >= sizeof(d1->d_name)) >- long_len = sizeof(d1->d_name) - 1; >- if (short_len >= sizeof(d1->d_name)) >- short_len = sizeof(d1->d_name) - 1; >- >- if (copy_to_user(d2->d_name, longname, long_len) || >- put_user(0, d2->d_name + long_len) || >- put_user(long_len, &d2->d_reclen) || >- put_user(ino, &d2->d_ino) || >- put_user(offset, &d2->d_off) || >- copy_to_user(d1->d_name, shortname, short_len) || >- put_user(0, d1->d_name + short_len) || >- put_user(short_len, &d1->d_reclen)) >- goto efault; >+ struct fat_ioctl_filldir_callback buf; >+ int ret; >+ >+ buf.dirent = dirent; >+ buf.result = 0; >+ mutex_lock(&inode->i_mutex); >+ ret = -ENOENT; >+ if (!IS_DEADDIR(inode)) { >+ ret = __fat_readdir(inode, filp, &buf, filldir, >+ short_only, both); > } >- return 0; >-efault: >- buf->result = -EFAULT; >- return -EFAULT; >+ mutex_unlock(&inode->i_mutex); >+ if (ret >= 0) >+ ret = buf.result; >+ return ret; > } > >-static int fat_dir_ioctl(struct inode * inode, struct file * filp, >- unsigned int cmd, unsigned long arg) >+static int fat_dir_ioctl(struct inode *inode, struct file *filp, >+ unsigned int cmd, unsigned long arg) > { >- struct fat_ioctl_filldir_callback buf; >- struct dirent __user *d1; >- int ret, short_only, both; >+ struct dirent __user *d1 = (struct dirent __user *)arg; >+ int short_only, both; > > switch (cmd) { > case VFAT_IOCTL_READDIR_SHORT: >@@ -717,7 +740,6 @@ static int fat_dir_ioctl(struct inode * inode, struct file * filp, > return fat_generic_ioctl(inode, filp, cmd, arg); > } > >- d1 = (struct dirent __user *)arg; > if (!access_ok(VERIFY_WRITE, d1, sizeof(struct dirent[2]))) > return -EFAULT; > /* >@@ -728,69 +750,48 @@ static int fat_dir_ioctl(struct inode * inode, struct file * filp, > if (put_user(0, &d1->d_reclen)) > return -EFAULT; > >- buf.dirent = d1; >- buf.result = 0; >- mutex_lock(&inode->i_mutex); >- ret = -ENOENT; >- if (!IS_DEADDIR(inode)) { >- ret = __fat_readdir(inode, filp, &buf, fat_ioctl_filldir, >- short_only, both); >- } >- mutex_unlock(&inode->i_mutex); >- if (ret >= 0) >- ret = buf.result; >- return ret; >+ return fat_ioctl_readdir(inode, filp, d1, fat_ioctl_filldir, >+ short_only, both); > } > > #ifdef CONFIG_COMPAT > #define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2]) > #define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2]) > >-static long fat_compat_put_dirent32(struct dirent *d, >- struct compat_dirent __user *d32) >-{ >- if (!access_ok(VERIFY_WRITE, d32, sizeof(struct compat_dirent))) >- return -EFAULT; >- >- __put_user(d->d_ino, &d32->d_ino); >- __put_user(d->d_off, &d32->d_off); >- __put_user(d->d_reclen, &d32->d_reclen); >- if (__copy_to_user(d32->d_name, d->d_name, d->d_reclen)) >- return -EFAULT; >+FAT_IOCTL_FILLDIR_FUNC(fat_compat_ioctl_filldir, compat_dirent) > >- return 0; >-} >- >-static long fat_compat_dir_ioctl(struct file *file, unsigned cmd, >+static long fat_compat_dir_ioctl(struct file *filp, unsigned cmd, > unsigned long arg) > { >- struct compat_dirent __user *p = compat_ptr(arg); >- int ret; >- mm_segment_t oldfs = get_fs(); >- struct dirent d[2]; >+ struct inode *inode = filp->f_path.dentry->d_inode; >+ struct compat_dirent __user *d1 = compat_ptr(arg); >+ int short_only, both; > > switch (cmd) { >- case VFAT_IOCTL_READDIR_BOTH32: >- cmd = VFAT_IOCTL_READDIR_BOTH; >- break; > case VFAT_IOCTL_READDIR_SHORT32: >- cmd = VFAT_IOCTL_READDIR_SHORT; >+ short_only = 1; >+ both = 0; >+ break; >+ case VFAT_IOCTL_READDIR_BOTH32: >+ short_only = 0; >+ both = 1; > break; > default: > return -ENOIOCTLCMD; > } > >- set_fs(KERNEL_DS); >- lock_kernel(); >- ret = fat_dir_ioctl(file->f_path.dentry->d_inode, file, >- cmd, (unsigned long) &d); >- unlock_kernel(); >- set_fs(oldfs); >- if (ret >= 0) { >- ret |= fat_compat_put_dirent32(&d[0], p); >- ret |= fat_compat_put_dirent32(&d[1], p + 1); >- } >- return ret; >+ if (!access_ok(VERIFY_WRITE, d1, sizeof(struct compat_dirent[2]))) >+ return -EFAULT; >+ /* >+ * Yes, we don't need this put_user() absolutely. However old >+ * code didn't return the right value. So, app use this value, >+ * in order to check whether it is EOF. >+ */ >+ if (put_user(0, &d1->d_reclen)) >+ return -EFAULT; >+ >+ return fat_ioctl_readdir(inode, filp, d1, fat_compat_ioctl_filldir, >+ short_only, both); > } > #endif /* CONFIG_COMPAT */ > >diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c >index 5065baa..3760d02 100644 >--- a/fs/jfs/jfs_logmgr.c >+++ b/fs/jfs/jfs_logmgr.c >@@ -2354,12 +2354,13 @@ int jfsIOWait(void *arg) > lbmStartIO(bp); > spin_lock_irq(&log_redrive_lock); > } >- spin_unlock_irq(&log_redrive_lock); > > if (freezing(current)) { >+ spin_unlock_irq(&log_redrive_lock); > refrigerator(); > } else { > set_current_state(TASK_INTERRUPTIBLE); >+ spin_unlock_irq(&log_redrive_lock); > schedule(); > current->state = TASK_RUNNING; > } >diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c >index 6f24768..79bd03b 100644 >--- a/fs/nfsd/export.c >+++ b/fs/nfsd/export.c >@@ -469,6 +469,13 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) > nd.dentry = NULL; > exp.ex_path = NULL; > >+ /* fs locations */ >+ exp.ex_fslocs.locations = NULL; >+ exp.ex_fslocs.locations_count = 0; >+ exp.ex_fslocs.migrated = 0; >+ >+ exp.ex_uuid = NULL; >+ > if (mesg[mlen-1] != '\n') > return -EINVAL; > mesg[mlen-1] = 0; >@@ -509,13 +516,6 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) > if (exp.h.expiry_time == 0) > goto out; > >- /* fs locations */ >- exp.ex_fslocs.locations = NULL; >- exp.ex_fslocs.locations_count = 0; >- exp.ex_fslocs.migrated = 0; >- >- exp.ex_uuid = NULL; >- > /* flags */ > err = get_int(&mesg, &an_int); > if (err == -ENOENT) >diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c >index c8178b7..2cac562 100644 >--- a/fs/reiserfs/xattr.c >+++ b/fs/reiserfs/xattr.c >@@ -68,7 +68,7 @@ static struct dentry *get_xa_root(struct super_block *sb, int flags) > if (!privroot) > return ERR_PTR(-ENODATA); > >- mutex_lock(&privroot->d_inode->i_mutex); >+ mutex_lock_nested(&privroot->d_inode->i_mutex, I_MUTEX_XATTR); > if (REISERFS_SB(sb)->xattr_root) { > xaroot = dget(REISERFS_SB(sb)->xattr_root); > goto out; >diff --git a/fs/udf/namei.c b/fs/udf/namei.c >index fe361cd..b254375 100644 >--- a/fs/udf/namei.c >+++ b/fs/udf/namei.c >@@ -878,7 +878,7 @@ static int udf_rmdir(struct inode * dir, struct dentry * dentry) > inode->i_nlink); > clear_nlink(inode); > inode->i_size = 0; >- inode_dec_link_count(inode); >+ inode_dec_link_count(dir); > inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); > mark_inode_dirty(dir); > >diff --git a/include/asm-arm/arch-iop13xx/iop13xx.h b/include/asm-arm/arch-iop13xx/iop13xx.h >index d26b755..74d7498 100644 >--- a/include/asm-arm/arch-iop13xx/iop13xx.h >+++ b/include/asm-arm/arch-iop13xx/iop13xx.h >@@ -27,19 +27,24 @@ static inline int iop13xx_cpu_id(void) > #define IOP13XX_PCI_OFFSET IOP13XX_MAX_RAM_SIZE > > /* PCI MAP >- * 0x0000.0000 - 0x8000.0000 1:1 mapping with Physical RAM >- * 0x8000.0000 - 0x8800.0000 PCIX/PCIE memory window (128MB) >-*/ >+ * bus range cpu phys cpu virt note >+ * 0x0000.0000 + 2GB (n/a) (n/a) inbound, 1:1 mapping with Physical RAM >+ * 0x8000.0000 + 928M 0x1.8000.0000 (ioremap) PCIX outbound memory window >+ * 0x8000.0000 + 928M 0x2.8000.0000 (ioremap) PCIE outbound memory window >+ * >+ * IO MAP >+ * 0x1000 + 64K 0x0.fffb.1000 0xfec6.1000 PCIX outbound i/o window >+ * 0x1000 + 64K 0x0.fffd.1000 0xfed7.1000 PCIE outbound i/o window >+ */ > #define IOP13XX_PCIX_IO_WINDOW_SIZE 0x10000UL > #define IOP13XX_PCIX_LOWER_IO_PA 0xfffb0000UL > #define IOP13XX_PCIX_LOWER_IO_VA 0xfec60000UL >-#define IOP13XX_PCIX_LOWER_IO_BA 0x0fff0000UL >+#define IOP13XX_PCIX_LOWER_IO_BA 0x0UL /* OIOTVR */ >+#define IOP13XX_PCIX_IO_BUS_OFFSET 0x1000UL > #define IOP13XX_PCIX_UPPER_IO_PA (IOP13XX_PCIX_LOWER_IO_PA +\ > IOP13XX_PCIX_IO_WINDOW_SIZE - 1) > #define IOP13XX_PCIX_UPPER_IO_VA (IOP13XX_PCIX_LOWER_IO_VA +\ > IOP13XX_PCIX_IO_WINDOW_SIZE - 1) >-#define IOP13XX_PCIX_IO_OFFSET (IOP13XX_PCIX_LOWER_IO_VA -\ >- IOP13XX_PCIX_LOWER_IO_BA) > #define IOP13XX_PCIX_IO_PHYS_TO_VIRT(addr) (u32) ((u32) addr -\ > (IOP13XX_PCIX_LOWER_IO_PA\ > - IOP13XX_PCIX_LOWER_IO_VA)) >@@ -65,15 +70,14 @@ static inline int iop13xx_cpu_id(void) > #define IOP13XX_PCIE_IO_WINDOW_SIZE 0x10000UL > #define IOP13XX_PCIE_LOWER_IO_PA 0xfffd0000UL > #define IOP13XX_PCIE_LOWER_IO_VA 0xfed70000UL >-#define IOP13XX_PCIE_LOWER_IO_BA 0x0fff0000UL >+#define IOP13XX_PCIE_LOWER_IO_BA 0x0UL /* OIOTVR */ >+#define IOP13XX_PCIE_IO_BUS_OFFSET 0x1000UL > #define IOP13XX_PCIE_UPPER_IO_PA (IOP13XX_PCIE_LOWER_IO_PA +\ > IOP13XX_PCIE_IO_WINDOW_SIZE - 1) > #define IOP13XX_PCIE_UPPER_IO_VA (IOP13XX_PCIE_LOWER_IO_VA +\ > IOP13XX_PCIE_IO_WINDOW_SIZE - 1) > #define IOP13XX_PCIE_UPPER_IO_BA (IOP13XX_PCIE_LOWER_IO_BA +\ > IOP13XX_PCIE_IO_WINDOW_SIZE - 1) >-#define IOP13XX_PCIE_IO_OFFSET (IOP13XX_PCIE_LOWER_IO_VA -\ >- IOP13XX_PCIE_LOWER_IO_BA) > #define IOP13XX_PCIE_IO_PHYS_TO_VIRT(addr) (u32) ((u32) addr -\ > (IOP13XX_PCIE_LOWER_IO_PA\ > - IOP13XX_PCIE_LOWER_IO_VA)) >diff --git a/include/asm-sparc64/openprom.h b/include/asm-sparc64/openprom.h >index e01b805..26ec046 100644 >--- a/include/asm-sparc64/openprom.h >+++ b/include/asm-sparc64/openprom.h >@@ -177,7 +177,7 @@ struct linux_nodeops { > /* More fun PROM structures for device probing. */ > #define PROMREG_MAX 24 > #define PROMVADDR_MAX 16 >-#define PROMINTR_MAX 15 >+#define PROMINTR_MAX 32 > > struct linux_prom_registers { > unsigned which_io; /* hi part of physical address */ >diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h >index daa4940..bf92c26 100644 >--- a/include/linux/clocksource.h >+++ b/include/linux/clocksource.h >@@ -48,6 +48,7 @@ struct clocksource; > * @shift: cycle to nanosecond divisor (power of two) > * @flags: flags describing special properties > * @vread: vsyscall based read >+ * @resume: resume function for the clocksource, if necessary > * @cycle_interval: Used internally by timekeeping core, please ignore. > * @xtime_interval: Used internally by timekeeping core, please ignore. > */ >@@ -61,6 +62,7 @@ struct clocksource { > u32 shift; > unsigned long flags; > cycle_t (*vread)(void); >+ void (*resume)(void); > > /* timekeeping specific data, ignore */ > cycle_t cycle_last, cycle_interval; >@@ -198,6 +200,7 @@ static inline void clocksource_calculate_interval(struct clocksource *c, > extern int clocksource_register(struct clocksource*); > extern struct clocksource* clocksource_get_next(void); > extern void clocksource_change_rating(struct clocksource *cs, int rating); >+extern void clocksource_resume(void); > > #ifdef CONFIG_GENERIC_TIME_VSYSCALL > extern void update_vsyscall(struct timespec *ts, struct clocksource *c); >diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h >index 1a52854..b1b0f68 100644 >--- a/include/linux/netdevice.h >+++ b/include/linux/netdevice.h >@@ -647,8 +647,10 @@ static inline void netif_start_queue(struct net_device *dev) > static inline void netif_wake_queue(struct net_device *dev) > { > #ifdef CONFIG_NETPOLL_TRAP >- if (netpoll_trap()) >+ if (netpoll_trap()) { >+ clear_bit(__LINK_STATE_XOFF, &dev->state); > return; >+ } > #endif > if (test_and_clear_bit(__LINK_STATE_XOFF, &dev->state)) > __netif_schedule(dev); >@@ -656,10 +658,6 @@ static inline void netif_wake_queue(struct net_device *dev) > > static inline void netif_stop_queue(struct net_device *dev) > { >-#ifdef CONFIG_NETPOLL_TRAP >- if (netpoll_trap()) >- return; >-#endif > set_bit(__LINK_STATE_XOFF, &dev->state); > } > >diff --git a/include/linux/netfilter/nf_conntrack_proto_gre.h b/include/linux/netfilter/nf_conntrack_proto_gre.h >index 4e6bbce..535e421 100644 >--- a/include/linux/netfilter/nf_conntrack_proto_gre.h >+++ b/include/linux/netfilter/nf_conntrack_proto_gre.h >@@ -87,24 +87,6 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir, > /* delete keymap entries */ > void nf_ct_gre_keymap_destroy(struct nf_conn *ct); > >-/* get pointer to gre key, if present */ >-static inline __be32 *gre_key(struct gre_hdr *greh) >-{ >- if (!greh->key) >- return NULL; >- if (greh->csum || greh->routing) >- return (__be32 *)(greh+sizeof(*greh)+4); >- return (__be32 *)(greh+sizeof(*greh)); >-} >- >-/* get pointer ot gre csum, if present */ >-static inline __sum16 *gre_csum(struct gre_hdr *greh) >-{ >- if (!greh->csum) >- return NULL; >- return (__sum16 *)(greh+sizeof(*greh)); >-} >- > extern void nf_ct_gre_keymap_flush(void); > extern void nf_nat_need_gre(void); > >diff --git a/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h b/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h >index e371e0f..d0f36f5 100644 >--- a/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h >+++ b/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h >@@ -90,25 +90,6 @@ int ip_ct_gre_keymap_add(struct ip_conntrack *ct, > /* delete keymap entries */ > void ip_ct_gre_keymap_destroy(struct ip_conntrack *ct); > >- >-/* get pointer to gre key, if present */ >-static inline __be32 *gre_key(struct gre_hdr *greh) >-{ >- if (!greh->key) >- return NULL; >- if (greh->csum || greh->routing) >- return (__be32 *) (greh+sizeof(*greh)+4); >- return (__be32 *) (greh+sizeof(*greh)); >-} >- >-/* get pointer ot gre csum, if present */ >-static inline __sum16 *gre_csum(struct gre_hdr *greh) >-{ >- if (!greh->csum) >- return NULL; >- return (__sum16 *) (greh+sizeof(*greh)); >-} >- > #endif /* __KERNEL__ */ > > #endif /* _CONNTRACK_PROTO_GRE_H */ >diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c >index fe5c7db..5baee91 100644 >--- a/kernel/time/clocksource.c >+++ b/kernel/time/clocksource.c >@@ -74,6 +74,8 @@ static struct clocksource *watchdog; > static struct timer_list watchdog_timer; > static DEFINE_SPINLOCK(watchdog_lock); > static cycle_t watchdog_last; >+static int watchdog_resumed; >+ > /* > * Interval: 0.5sec Treshold: 0.0625s > */ >@@ -98,15 +100,26 @@ static void clocksource_watchdog(unsigned long data) > struct clocksource *cs, *tmp; > cycle_t csnow, wdnow; > int64_t wd_nsec, cs_nsec; >+ int resumed; > > spin_lock(&watchdog_lock); > >+ resumed = watchdog_resumed; >+ if (unlikely(resumed)) >+ watchdog_resumed = 0; >+ > wdnow = watchdog->read(); > wd_nsec = cyc2ns(watchdog, (wdnow - watchdog_last) & watchdog->mask); > watchdog_last = wdnow; > > list_for_each_entry_safe(cs, tmp, &watchdog_list, wd_list) { > csnow = cs->read(); >+ >+ if (unlikely(resumed)) { >+ cs->wd_last = csnow; >+ continue; >+ } >+ > /* Initialized ? */ > if (!(cs->flags & CLOCK_SOURCE_WATCHDOG)) { > if ((cs->flags & CLOCK_SOURCE_IS_CONTINUOUS) && >@@ -136,6 +149,13 @@ static void clocksource_watchdog(unsigned long data) > } > spin_unlock(&watchdog_lock); > } >+static void clocksource_resume_watchdog(void) >+{ >+ spin_lock(&watchdog_lock); >+ watchdog_resumed = 1; >+ spin_unlock(&watchdog_lock); >+} >+ > static void clocksource_check_watchdog(struct clocksource *cs) > { > struct clocksource *cse; >@@ -182,9 +202,34 @@ static void clocksource_check_watchdog(struct clocksource *cs) > if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS) > cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES; > } >+ >+static inline void clocksource_resume_watchdog(void) { } > #endif > > /** >+ * clocksource_resume - resume the clocksource(s) >+ */ >+void clocksource_resume(void) >+{ >+ struct list_head *tmp; >+ unsigned long flags; >+ >+ spin_lock_irqsave(&clocksource_lock, flags); >+ >+ list_for_each(tmp, &clocksource_list) { >+ struct clocksource *cs; >+ >+ cs = list_entry(tmp, struct clocksource, list); >+ if (cs->resume) >+ cs->resume(); >+ } >+ >+ clocksource_resume_watchdog(); >+ >+ spin_unlock_irqrestore(&clocksource_lock, flags); >+} >+ >+/** > * clocksource_get_next - Returns the selected clocksource > * > */ >diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c >index bfda3f7..a96ec9a 100644 >--- a/kernel/time/tick-common.c >+++ b/kernel/time/tick-common.c >@@ -31,7 +31,7 @@ DEFINE_PER_CPU(struct tick_device, tick_cpu_device); > */ > ktime_t tick_next_period; > ktime_t tick_period; >-static int tick_do_timer_cpu = -1; >+int tick_do_timer_cpu __read_mostly = -1; > DEFINE_SPINLOCK(tick_device_lock); > > /* >@@ -295,6 +295,12 @@ static void tick_shutdown(unsigned int *cpup) > clockevents_exchange_device(dev, NULL); > td->evtdev = NULL; > } >+ /* Transfer the do_timer job away from this cpu */ >+ if (*cpup == tick_do_timer_cpu) { >+ int cpu = first_cpu(cpu_online_map); >+ >+ tick_do_timer_cpu = (cpu != NR_CPUS) ? cpu : -1; >+ } > spin_unlock_irqrestore(&tick_device_lock, flags); > } > >diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h >index c9d203b..bb13f27 100644 >--- a/kernel/time/tick-internal.h >+++ b/kernel/time/tick-internal.h >@@ -5,6 +5,7 @@ DECLARE_PER_CPU(struct tick_device, tick_cpu_device); > extern spinlock_t tick_device_lock; > extern ktime_t tick_next_period; > extern ktime_t tick_period; >+extern int tick_do_timer_cpu __read_mostly; > > extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast); > extern void tick_handle_periodic(struct clock_event_device *dev); >diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c >index 51556b9..f4fc867 100644 >--- a/kernel/time/tick-sched.c >+++ b/kernel/time/tick-sched.c >@@ -221,6 +221,18 @@ void tick_nohz_stop_sched_tick(void) > ts->tick_stopped = 1; > ts->idle_jiffies = last_jiffies; > } >+ >+ /* >+ * If this cpu is the one which updates jiffies, then >+ * give up the assignment and let it be taken by the >+ * cpu which runs the tick timer next, which might be >+ * this cpu as well. If we don't drop this here the >+ * jiffies might be stale and do_timer() never >+ * invoked. >+ */ >+ if (cpu == tick_do_timer_cpu) >+ tick_do_timer_cpu = -1; >+ > /* > * calculate the expiry time for the next timer wheel > * timer >@@ -338,12 +350,24 @@ static void tick_nohz_handler(struct clock_event_device *dev) > { > struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched); > struct pt_regs *regs = get_irq_regs(); >+ int cpu = smp_processor_id(); > ktime_t now = ktime_get(); > > dev->next_event.tv64 = KTIME_MAX; > >+ /* >+ * Check if the do_timer duty was dropped. We don't care about >+ * concurrency: This happens only when the cpu in charge went >+ * into a long sleep. If two cpus happen to assign themself to >+ * this duty, then the jiffies update is still serialized by >+ * xtime_lock. >+ */ >+ if (unlikely(tick_do_timer_cpu == -1)) >+ tick_do_timer_cpu = cpu; >+ > /* Check, if the jiffies need an update */ >- tick_do_update_jiffies64(now); >+ if (tick_do_timer_cpu == cpu) >+ tick_do_update_jiffies64(now); > > /* > * When we are idle and the tick is stopped, we have to touch >@@ -431,9 +455,23 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer) > struct hrtimer_cpu_base *base = timer->base->cpu_base; > struct pt_regs *regs = get_irq_regs(); > ktime_t now = ktime_get(); >+ int cpu = smp_processor_id(); >+ >+#ifdef CONFIG_NO_HZ >+ /* >+ * Check if the do_timer duty was dropped. We don't care about >+ * concurrency: This happens only when the cpu in charge went >+ * into a long sleep. If two cpus happen to assign themself to >+ * this duty, then the jiffies update is still serialized by >+ * xtime_lock. >+ */ >+ if (unlikely(tick_do_timer_cpu == -1)) >+ tick_do_timer_cpu = cpu; >+#endif > > /* Check, if the jiffies need an update */ >- tick_do_update_jiffies64(now); >+ if (tick_do_timer_cpu == cpu) >+ tick_do_update_jiffies64(now); > > /* > * Do not call, when we are not in irq context and have >diff --git a/kernel/timer.c b/kernel/timer.c >index dd6c2c1..e045774 100644 >--- a/kernel/timer.c >+++ b/kernel/timer.c >@@ -1903,6 +1903,8 @@ unregister_time_interpolator(struct time_interpolator *ti) > prev = &curr->next; > } > >+ clocksource_resume(); >+ > write_seqlock_irqsave(&xtime_lock, flags); > if (ti == time_interpolator) { > /* we lost the best time-interpolator: */ >diff --git a/lib/zlib_inflate/inflate.c b/lib/zlib_inflate/inflate.c >index fceb97c..7e1e311 100644 >--- a/lib/zlib_inflate/inflate.c >+++ b/lib/zlib_inflate/inflate.c >@@ -743,12 +743,14 @@ int zlib_inflate(z_streamp strm, int flush) > > strm->data_type = state->bits + (state->last ? 64 : 0) + > (state->mode == TYPE ? 128 : 0); >- if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) >- ret = Z_BUF_ERROR; > > if (flush == Z_PACKET_FLUSH && ret == Z_OK && >- (strm->avail_out != 0 || strm->avail_in == 0)) >+ strm->avail_out != 0 && strm->avail_in == 0) > return zlib_inflateSyncPacket(strm); >+ >+ if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) >+ ret = Z_BUF_ERROR; >+ > return ret; > } > >diff --git a/mm/hugetlb.c b/mm/hugetlb.c >index 36db012..88e708b 100644 >--- a/mm/hugetlb.c >+++ b/mm/hugetlb.c >@@ -140,6 +140,8 @@ static struct page *alloc_huge_page(struct vm_area_struct *vma, > return page; > > fail: >+ if (vma->vm_flags & VM_MAYSHARE) >+ resv_huge_pages++; > spin_unlock(&hugetlb_lock); > return NULL; > } >diff --git a/mm/oom_kill.c b/mm/oom_kill.c >index 3791edf..b3a3dd6 100644 >--- a/mm/oom_kill.c >+++ b/mm/oom_kill.c >@@ -397,6 +397,7 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order) > struct task_struct *p; > unsigned long points = 0; > unsigned long freed = 0; >+ int constraint; > > blocking_notifier_call_chain(&oom_notify_list, 0, &freed); > if (freed > 0) >@@ -411,14 +412,15 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order) > show_mem(); > } > >- cpuset_lock(); >- read_lock(&tasklist_lock); >- > /* > * Check if there were limitations on the allocation (only relevant for > * NUMA) that may require different handling. > */ >- switch (constrained_alloc(zonelist, gfp_mask)) { >+ constraint = constrained_alloc(zonelist, gfp_mask); >+ cpuset_lock(); >+ read_lock(&tasklist_lock); >+ >+ switch (constraint) { > case CONSTRAINT_MEMORY_POLICY: > oom_kill_process(current, points, > "No available memory (MPOL_BIND)"); >diff --git a/mm/slob.c b/mm/slob.c >index 5adc29c..c683d35 100644 >--- a/mm/slob.c >+++ b/mm/slob.c >@@ -150,15 +150,6 @@ static void slob_free(void *block, int size) > spin_unlock_irqrestore(&slob_lock, flags); > } > >-static int FASTCALL(find_order(int size)); >-static int fastcall find_order(int size) >-{ >- int order = 0; >- for ( ; size > 4096 ; size >>=1) >- order++; >- return order; >-} >- > void *__kmalloc(size_t size, gfp_t gfp) > { > slob_t *m; >@@ -174,7 +165,7 @@ void *__kmalloc(size_t size, gfp_t gfp) > if (!bb) > return 0; > >- bb->order = find_order(size); >+ bb->order = get_order(size); > bb->pages = (void *)__get_free_pages(gfp, bb->order); > > if (bb->pages) { >@@ -284,7 +275,7 @@ void *kmem_cache_alloc(struct kmem_cache *c, gfp_t flags) > if (c->size < PAGE_SIZE) > b = slob_alloc(c->size, flags, c->align); > else >- b = (void *)__get_free_pages(flags, find_order(c->size)); >+ b = (void *)__get_free_pages(flags, get_order(c->size)); > > if (c->ctor) > c->ctor(b, c, SLAB_CTOR_CONSTRUCTOR); >@@ -311,7 +302,7 @@ void kmem_cache_free(struct kmem_cache *c, void *b) > if (c->size < PAGE_SIZE) > slob_free(b, c->size); > else >- free_pages((unsigned long)b, find_order(c->size)); >+ free_pages((unsigned long)b, get_order(c->size)); > } > EXPORT_SYMBOL(kmem_cache_free); > >diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c >index 23b99ae..75bd597 100644 >--- a/net/ipv4/netfilter/ip_conntrack_core.c >+++ b/net/ipv4/netfilter/ip_conntrack_core.c >@@ -302,7 +302,6 @@ destroy_conntrack(struct nf_conntrack *nfct) > { > struct ip_conntrack *ct = (struct ip_conntrack *)nfct; > struct ip_conntrack_protocol *proto; >- struct ip_conntrack_helper *helper; > typeof(ip_conntrack_destroyed) destroyed; > > DEBUGP("destroy_conntrack(%p)\n", ct); >@@ -312,10 +311,6 @@ destroy_conntrack(struct nf_conntrack *nfct) > ip_conntrack_event(IPCT_DESTROY, ct); > set_bit(IPS_DYING_BIT, &ct->status); > >- helper = ct->helper; >- if (helper && helper->destroy) >- helper->destroy(ct); >- > /* To make sure we don't get any weird locking issues here: > * destroy_conntrack() MUST NOT be called with a write lock > * to ip_conntrack_lock!!! -HW */ >@@ -356,6 +351,11 @@ destroy_conntrack(struct nf_conntrack *nfct) > static void death_by_timeout(unsigned long ul_conntrack) > { > struct ip_conntrack *ct = (void *)ul_conntrack; >+ struct ip_conntrack_helper *helper; >+ >+ helper = ct->helper; >+ if (helper && helper->destroy) >+ helper->destroy(ct); > > write_lock_bh(&ip_conntrack_lock); > /* Inside lock so preempt is disabled on module removal path. >diff --git a/net/ipv4/netfilter/ip_nat_proto_gre.c b/net/ipv4/netfilter/ip_nat_proto_gre.c >index 9581020..e3146a3 100644 >--- a/net/ipv4/netfilter/ip_nat_proto_gre.c >+++ b/net/ipv4/netfilter/ip_nat_proto_gre.c >@@ -70,6 +70,11 @@ gre_unique_tuple(struct ip_conntrack_tuple *tuple, > __be16 *keyptr; > unsigned int min, i, range_size; > >+ /* If there is no master conntrack we are not PPTP, >+ do not change tuples */ >+ if (!conntrack->master) >+ return 0; >+ > if (maniptype == IP_NAT_MANIP_SRC) > keyptr = &tuple->src.u.gre.key; > else >@@ -122,18 +127,9 @@ gre_manip_pkt(struct sk_buff **pskb, > if (maniptype == IP_NAT_MANIP_DST) { > /* key manipulation is always dest */ > switch (greh->version) { >- case 0: >- if (!greh->key) { >- DEBUGP("can't nat GRE w/o key\n"); >- break; >- } >- if (greh->csum) { >- /* FIXME: Never tested this code... */ >- nf_proto_csum_replace4(gre_csum(greh), *pskb, >- *(gre_key(greh)), >- tuple->dst.u.gre.key, 0); >- } >- *(gre_key(greh)) = tuple->dst.u.gre.key; >+ case GRE_VERSION_1701: >+ /* We do not currently NAT any GREv0 packets. >+ * Try to behave like "ip_nat_proto_unknown" */ > break; > case GRE_VERSION_PPTP: > DEBUGP("call_id -> 0x%04x\n", >diff --git a/net/ipv4/netfilter/nf_nat_proto_gre.c b/net/ipv4/netfilter/nf_nat_proto_gre.c >index e5a34c1..ca3ff84 100644 >--- a/net/ipv4/netfilter/nf_nat_proto_gre.c >+++ b/net/ipv4/netfilter/nf_nat_proto_gre.c >@@ -72,6 +72,11 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple, > __be16 *keyptr; > unsigned int min, i, range_size; > >+ /* If there is no master conntrack we are not PPTP, >+ do not change tuples */ >+ if (!conntrack->master) >+ return 0; >+ > if (maniptype == IP_NAT_MANIP_SRC) > keyptr = &tuple->src.u.gre.key; > else >@@ -122,18 +127,9 @@ gre_manip_pkt(struct sk_buff **pskb, unsigned int iphdroff, > if (maniptype != IP_NAT_MANIP_DST) > return 1; > switch (greh->version) { >- case 0: >- if (!greh->key) { >- DEBUGP("can't nat GRE w/o key\n"); >- break; >- } >- if (greh->csum) { >- /* FIXME: Never tested this code... */ >- nf_proto_csum_replace4(gre_csum(greh), *pskb, >- *(gre_key(greh)), >- tuple->dst.u.gre.key, 0); >- } >- *(gre_key(greh)) = tuple->dst.u.gre.key; >+ case GRE_VERSION_1701: >+ /* We do not currently NAT any GREv0 packets. >+ * Try to behave like "nf_nat_proto_unknown" */ > break; > case GRE_VERSION_PPTP: > DEBUGP("call_id -> 0x%04x\n", ntohs(tuple->dst.u.gre.key)); >diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c >index 3834b10..824c6b9 100644 >--- a/net/ipv4/tcp.c >+++ b/net/ipv4/tcp.c >@@ -1759,8 +1759,7 @@ int tcp_disconnect(struct sock *sk, int flags) > tcp_clear_retrans(tp); > inet_csk_delack_init(sk); > sk->sk_send_head = NULL; >- tp->rx_opt.saw_tstamp = 0; >- tcp_sack_reset(&tp->rx_opt); >+ memset(&tp->rx_opt, 0, sizeof(tp->rx_opt)); > __sk_dst_reset(sk); > > BUG_TRAP(!inet->num || icsk->icsk_bind_hash); >diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c >index 452a82c..a541137 100644 >--- a/net/ipv6/addrconf.c >+++ b/net/ipv6/addrconf.c >@@ -2281,8 +2281,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, > break; > > case NETDEV_CHANGENAME: >-#ifdef CONFIG_SYSCTL > if (idev) { >+ snmp6_unregister_dev(idev); >+#ifdef CONFIG_SYSCTL > addrconf_sysctl_unregister(&idev->cnf); > neigh_sysctl_unregister(idev->nd_parms); > neigh_sysctl_register(dev, idev->nd_parms, >@@ -2290,8 +2291,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, > &ndisc_ifinfo_sysctl_change, > NULL); > addrconf_sysctl_register(idev, &idev->cnf); >- } > #endif >+ snmp6_register_dev(idev); >+ } > break; > }; > >@@ -4060,6 +4062,10 @@ int __init addrconf_init(void) > return err; > > ip6_null_entry.rt6i_idev = in6_dev_get(&loopback_dev); >+#ifdef CONFIG_IPV6_MULTIPLE_TABLES >+ ip6_prohibit_entry.rt6i_idev = in6_dev_get(&loopback_dev); >+ ip6_blk_hole_entry.rt6i_idev = in6_dev_get(&loopback_dev); >+#endif > > register_netdevice_notifier(&ipv6_dev_notf); > >diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c >index 3205ec9..794b930 100644 >--- a/net/ipv6/exthdrs.c >+++ b/net/ipv6/exthdrs.c >@@ -652,6 +652,14 @@ EXPORT_SYMBOL_GPL(ipv6_invert_rthdr); > Hop-by-hop options. > **********************************/ > >+/* >+ * Note: we cannot rely on skb->dst before we assign it in ip6_route_input(). >+ */ >+static inline struct inet6_dev *ipv6_skb_idev(struct sk_buff *skb) >+{ >+ return skb->dst ? ip6_dst_idev(skb->dst) : __in6_dev_get(skb->dev); >+} >+ > /* Router Alert as of RFC 2711 */ > > static int ipv6_hop_ra(struct sk_buff **skbp, int optoff) >@@ -678,25 +686,25 @@ static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff) > if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) { > LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", > skb->nh.raw[optoff+1]); >- IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), >+ IP6_INC_STATS_BH(ipv6_skb_idev(skb), > IPSTATS_MIB_INHDRERRORS); > goto drop; > } > > pkt_len = ntohl(*(__be32*)(skb->nh.raw+optoff+2)); > if (pkt_len <= IPV6_MAXPLEN) { >- IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); >+ IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS); > icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2); > return 0; > } > if (skb->nh.ipv6h->payload_len) { >- IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); >+ IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS); > icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff); > return 0; > } > > if (pkt_len > skb->len - sizeof(struct ipv6hdr)) { >- IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INTRUNCATEDPKTS); >+ IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INTRUNCATEDPKTS); > goto drop; > } > >diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c >index 61e7a6c..1b34ee5 100644 >--- a/net/ipv6/ip6_input.c >+++ b/net/ipv6/ip6_input.c >@@ -235,7 +235,7 @@ int ip6_mc_input(struct sk_buff *skb) > IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS); > > hdr = skb->nh.ipv6h; >- deliver = likely(!(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI))) || >+ deliver = unlikely(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI)) || > ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL); > > /* >diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c >index 3055169..9fa3ffb 100644 >--- a/net/ipv6/ip6_output.c >+++ b/net/ipv6/ip6_output.c >@@ -449,10 +449,17 @@ int ip6_forward(struct sk_buff *skb) > */ > if (xrlim_allow(dst, 1*HZ)) > ndisc_send_redirect(skb, n, target); >- } else if (ipv6_addr_type(&hdr->saddr)&(IPV6_ADDR_MULTICAST|IPV6_ADDR_LOOPBACK >- |IPV6_ADDR_LINKLOCAL)) { >+ } else { >+ int addrtype = ipv6_addr_type(&hdr->saddr); >+ > /* This check is security critical. */ >- goto error; >+ if (addrtype & (IPV6_ADDR_MULTICAST|IPV6_ADDR_LOOPBACK)) >+ goto error; >+ if (addrtype & IPV6_ADDR_LINKLOCAL) { >+ icmpv6_send(skb, ICMPV6_DEST_UNREACH, >+ ICMPV6_NOT_NEIGHBOUR, 0, skb->dev); >+ goto error; >+ } > } > > if (skb->len > dst_mtu(dst)) { >diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c >index fa3fb50..d57853d 100644 >--- a/net/ipv6/proc.c >+++ b/net/ipv6/proc.c >@@ -236,6 +236,7 @@ int snmp6_unregister_dev(struct inet6_dev *idev) > return -EINVAL; > remove_proc_entry(idev->stats.proc_dir_entry->name, > proc_net_devsnmp6); >+ idev->stats.proc_dir_entry = NULL; > return 0; > } > >diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c >index 93c4223..dff33cc 100644 >--- a/net/ipv6/xfrm6_tunnel.c >+++ b/net/ipv6/xfrm6_tunnel.c >@@ -261,7 +261,7 @@ static int xfrm6_tunnel_rcv(struct sk_buff *skb) > __be32 spi; > > spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr); >- return xfrm6_rcv_spi(skb, spi); >+ return xfrm6_rcv_spi(skb, spi) > 0 ? : 0; > } > > static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt, >diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c >index b3a70eb..ce28fdd 100644 >--- a/net/netfilter/nf_conntrack_core.c >+++ b/net/netfilter/nf_conntrack_core.c >@@ -315,7 +315,6 @@ static void > destroy_conntrack(struct nf_conntrack *nfct) > { > struct nf_conn *ct = (struct nf_conn *)nfct; >- struct nf_conn_help *help = nfct_help(ct); > struct nf_conntrack_l3proto *l3proto; > struct nf_conntrack_l4proto *l4proto; > typeof(nf_conntrack_destroyed) destroyed; >@@ -327,9 +326,6 @@ destroy_conntrack(struct nf_conntrack *nfct) > nf_conntrack_event(IPCT_DESTROY, ct); > set_bit(IPS_DYING_BIT, &ct->status); > >- if (help && help->helper && help->helper->destroy) >- help->helper->destroy(ct); >- > /* To make sure we don't get any weird locking issues here: > * destroy_conntrack() MUST NOT be called with a write lock > * to nf_conntrack_lock!!! -HW */ >@@ -375,6 +371,10 @@ destroy_conntrack(struct nf_conntrack *nfct) > static void death_by_timeout(unsigned long ul_conntrack) > { > struct nf_conn *ct = (void *)ul_conntrack; >+ struct nf_conn_help *help = nfct_help(ct); >+ >+ if (help && help->helper && help->helper->destroy) >+ help->helper->destroy(ct); > > write_lock_bh(&nf_conntrack_lock); > /* Inside lock so preempt is disabled on module removal path. >diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c >index de889f2..a86f36b 100644 >--- a/net/sched/sch_prio.c >+++ b/net/sched/sch_prio.c >@@ -74,7 +74,7 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr) > band = res.classid; > } > band = TC_H_MIN(band) - 1; >- if (band > q->bands) >+ if (band >= q->bands) > return q->queues[q->prio2band[0]]; > > return q->queues[band]; >diff --git a/net/sctp/socket.c b/net/sctp/socket.c >index a1d026f..843c928 100644 >--- a/net/sctp/socket.c >+++ b/net/sctp/socket.c >@@ -3847,7 +3847,7 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len, > memcpy(&temp, &from->ipaddr, sizeof(temp)); > sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); > addrlen = sctp_get_af_specific(sk->sk_family)->sockaddr_len; >- if(space_left < addrlen) >+ if (space_left < addrlen) > return -ENOMEM; > if (copy_to_user(to, &temp, addrlen)) > return -EFAULT; >@@ -3936,8 +3936,9 @@ done: > /* Helper function that copies local addresses to user and returns the number > * of addresses copied. > */ >-static int sctp_copy_laddrs_to_user_old(struct sock *sk, __u16 port, int max_addrs, >- void __user *to) >+static int sctp_copy_laddrs_old(struct sock *sk, __u16 port, >+ int max_addrs, void *to, >+ int *bytes_copied) > { > struct list_head *pos, *next; > struct sctp_sockaddr_entry *addr; >@@ -3954,10 +3955,10 @@ static int sctp_copy_laddrs_to_user_old(struct sock *sk, __u16 port, int max_add > sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk), > &temp); > addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; >- if (copy_to_user(to, &temp, addrlen)) >- return -EFAULT; >+ memcpy(to, &temp, addrlen); > > to += addrlen; >+ *bytes_copied += addrlen; > cnt ++; > if (cnt >= max_addrs) break; > } >@@ -3965,8 +3966,8 @@ static int sctp_copy_laddrs_to_user_old(struct sock *sk, __u16 port, int max_add > return cnt; > } > >-static int sctp_copy_laddrs_to_user(struct sock *sk, __u16 port, >- void __user **to, size_t space_left) >+static int sctp_copy_laddrs(struct sock *sk, __u16 port, void *to, >+ size_t space_left, int *bytes_copied) > { > struct list_head *pos, *next; > struct sctp_sockaddr_entry *addr; >@@ -3983,14 +3984,14 @@ static int sctp_copy_laddrs_to_user(struct sock *sk, __u16 port, > sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk), > &temp); > addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; >- if(space_left<addrlen) >+ if (space_left < addrlen) > return -ENOMEM; >- if (copy_to_user(*to, &temp, addrlen)) >- return -EFAULT; >+ memcpy(to, &temp, addrlen); > >- *to += addrlen; >+ to += addrlen; > cnt ++; > space_left -= addrlen; >+ bytes_copied += addrlen; > } > > return cnt; >@@ -4014,6 +4015,9 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len, > int addrlen; > rwlock_t *addr_lock; > int err = 0; >+ void *addrs; >+ void *buf; >+ int bytes_copied = 0; > > if (len != sizeof(struct sctp_getaddrs_old)) > return -EINVAL; >@@ -4041,6 +4045,15 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len, > > to = getaddrs.addrs; > >+ /* Allocate space for a local instance of packed array to hold all >+ * the data. We store addresses here first and then put write them >+ * to the user in one shot. >+ */ >+ addrs = kmalloc(sizeof(union sctp_addr) * getaddrs.addr_num, >+ GFP_KERNEL); >+ if (!addrs) >+ return -ENOMEM; >+ > sctp_read_lock(addr_lock); > > /* If the endpoint is bound to 0.0.0.0 or ::0, get the valid >@@ -4050,38 +4063,42 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len, > addr = list_entry(bp->address_list.next, > struct sctp_sockaddr_entry, list); > if (sctp_is_any(&addr->a)) { >- cnt = sctp_copy_laddrs_to_user_old(sk, bp->port, >- getaddrs.addr_num, >- to); >- if (cnt < 0) { >- err = cnt; >- goto unlock; >- } >+ cnt = sctp_copy_laddrs_old(sk, bp->port, >+ getaddrs.addr_num, >+ addrs, &bytes_copied); > goto copy_getaddrs; > } > } > >+ buf = addrs; > list_for_each(pos, &bp->address_list) { > addr = list_entry(pos, struct sctp_sockaddr_entry, list); > memcpy(&temp, &addr->a, sizeof(temp)); > sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); > addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; >- if (copy_to_user(to, &temp, addrlen)) { >- err = -EFAULT; >- goto unlock; >- } >- to += addrlen; >+ memcpy(buf, &temp, addrlen); >+ buf += addrlen; >+ bytes_copied += addrlen; > cnt ++; > if (cnt >= getaddrs.addr_num) break; > } > > copy_getaddrs: >+ sctp_read_unlock(addr_lock); >+ >+ /* copy the entire address list into the user provided space */ >+ if (copy_to_user(to, addrs, bytes_copied)) { >+ err = -EFAULT; >+ goto error; >+ } >+ >+ /* copy the leading structure back to user */ > getaddrs.addr_num = cnt; > if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs_old))) > err = -EFAULT; > >-unlock: >- sctp_read_unlock(addr_lock); >+error: >+ kfree(addrs); > return err; > } > >@@ -4101,7 +4118,9 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, > rwlock_t *addr_lock; > int err = 0; > size_t space_left; >- int bytes_copied; >+ int bytes_copied = 0; >+ void *addrs; >+ void *buf; > > if (len <= sizeof(struct sctp_getaddrs)) > return -EINVAL; >@@ -4129,6 +4148,9 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, > to = optval + offsetof(struct sctp_getaddrs,addrs); > space_left = len - sizeof(struct sctp_getaddrs) - > offsetof(struct sctp_getaddrs,addrs); >+ addrs = kmalloc(space_left, GFP_KERNEL); >+ if (!addrs) >+ return -ENOMEM; > > sctp_read_lock(addr_lock); > >@@ -4139,41 +4161,47 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, > addr = list_entry(bp->address_list.next, > struct sctp_sockaddr_entry, list); > if (sctp_is_any(&addr->a)) { >- cnt = sctp_copy_laddrs_to_user(sk, bp->port, >- &to, space_left); >+ cnt = sctp_copy_laddrs(sk, bp->port, addrs, >+ space_left, &bytes_copied); > if (cnt < 0) { > err = cnt; >- goto unlock; >+ goto error; > } > goto copy_getaddrs; > } > } > >+ buf = addrs; > list_for_each(pos, &bp->address_list) { > addr = list_entry(pos, struct sctp_sockaddr_entry, list); > memcpy(&temp, &addr->a, sizeof(temp)); > sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); > addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; >- if(space_left < addrlen) >- return -ENOMEM; /*fixme: right error?*/ >- if (copy_to_user(to, &temp, addrlen)) { >- err = -EFAULT; >- goto unlock; >+ if (space_left < addrlen) { >+ err = -ENOMEM; /*fixme: right error?*/ >+ goto error; > } >- to += addrlen; >+ memcpy(buf, &temp, addrlen); >+ buf += addrlen; >+ bytes_copied += addrlen; > cnt ++; > space_left -= addrlen; > } > > copy_getaddrs: >+ sctp_read_unlock(addr_lock); >+ >+ if (copy_to_user(to, addrs, bytes_copied)) { >+ err = -EFAULT; >+ goto error; >+ } > if (put_user(cnt, &((struct sctp_getaddrs __user *)optval)->addr_num)) > return -EFAULT; >- bytes_copied = ((char __user *)to) - optval; > if (put_user(bytes_copied, optlen)) > return -EFAULT; > >-unlock: >- sctp_read_unlock(addr_lock); >+error: >+ kfree(addrs); > return err; > } > >@@ -4961,7 +4989,12 @@ int sctp_inet_listen(struct socket *sock, int backlog) > /* Allocate HMAC for generating cookie. */ > if (sctp_hmac_alg) { > tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); >- if (!tfm) { >+ if (IS_ERR(tfm)) { >+ if (net_ratelimit()) { >+ printk(KERN_INFO >+ "SCTP: failed to load transform for %s: %ld\n", >+ sctp_hmac_alg, PTR_ERR(tfm)); >+ } > err = -ENOSYS; > goto out; > } >diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c >index db298b5..c678f5f 100644 >--- a/net/sunrpc/auth_gss/svcauth_gss.c >+++ b/net/sunrpc/auth_gss/svcauth_gss.c >@@ -1196,13 +1196,7 @@ svcauth_gss_wrap_resp_integ(struct svc_rqst *rqstp) > if (xdr_buf_subsegment(resbuf, &integ_buf, integ_offset, > integ_len)) > BUG(); >- if (resbuf->page_len == 0 >- && resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE >- < PAGE_SIZE) { >- BUG_ON(resbuf->tail[0].iov_len); >- /* Use head for everything */ >- resv = &resbuf->head[0]; >- } else if (resbuf->tail[0].iov_base == NULL) { >+ if (resbuf->tail[0].iov_base == NULL) { > if (resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE > PAGE_SIZE) > goto out_err; > resbuf->tail[0].iov_base = resbuf->head[0].iov_base >diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c >index 785c3e3..ba89293 100644 >--- a/net/xfrm/xfrm_policy.c >+++ b/net/xfrm/xfrm_policy.c >@@ -782,6 +782,10 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete, > struct hlist_head *chain; > struct hlist_node *entry; > >+ *err = -ENOENT; >+ if (xfrm_policy_id2dir(id) != dir) >+ return NULL; >+ > *err = 0; > write_lock_bh(&xfrm_policy_lock); > chain = xfrm_policy_byidx + idx_hash(id); >diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c >index 6bc7e7c..8912c0f 100644 >--- a/scripts/basic/fixdep.c >+++ b/scripts/basic/fixdep.c >@@ -249,6 +249,8 @@ void parse_config_file(char *map, size_t len) > found: > if (!memcmp(q - 7, "_MODULE", 7)) > q -= 7; >+ if( (q-p-7) < 0 ) >+ continue; > use_config(p+7, q-p-7); > } > } >diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c >index c94291b..a6f8992 100644 >--- a/sound/pci/hda/patch_sigmatel.c >+++ b/sound/pci/hda/patch_sigmatel.c >@@ -1751,6 +1751,7 @@ static int stac92xx_resume(struct hda_codec *codec) > > stac92xx_init(codec); > stac92xx_set_config_regs(codec); >+ snd_hda_resume_ctls(codec, spec->mixer); > for (i = 0; i < spec->num_mixers; i++) > snd_hda_resume_ctls(codec, spec->mixers[i]); > if (spec->multiout.dig_out_nid)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 184852
:
124507
|
125486
| 125488