From: Greg Kroah-Hartman Date: Wed, 27 May 2009 21:47:22 +0000 (-0700) Subject: start .27 queue X-Git-Tag: v2.6.27.25~15 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d1499ff0466c1e5a5bfcecfc7d34e23a0a3d165a;p=thirdparty%2Fkernel%2Fstable-queue.git start .27 queue --- diff --git a/queue-2.6.27/bonding-fix-alb-mode-locking-regression.patch b/queue-2.6.27/bonding-fix-alb-mode-locking-regression.patch new file mode 100644 index 00000000000..8b5cc5d8e6a --- /dev/null +++ b/queue-2.6.27/bonding-fix-alb-mode-locking-regression.patch @@ -0,0 +1,55 @@ +From 19e28ed4c1db128ea59bf6f19b82a66904efe720 Mon Sep 17 00:00:00 2001 +From: Jay Vosburgh +Date: Tue, 26 May 2009 15:29:00 -0700 +Subject: bonding: fix alb mode locking regression + +From: Jay Vosburgh + +[ Upstream commit 815bcc2719c12b6f5b511706e2d19728e07f0b02 ] + +Fix locking issue in alb MAC address management; removed +incorrect locking and replaced with correct locking. This bug was +introduced in commit 059fe7a578fba5bbb0fdc0365bfcf6218fa25eb0 +("bonding: Convert locks to _bh, rework alb locking for new locking") + + Bug reported by Paul Smith , who also +tested the fix. + +Signed-off-by: Jay Vosburgh +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/bonding/bond_alb.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +--- a/drivers/net/bonding/bond_alb.c ++++ b/drivers/net/bonding/bond_alb.c +@@ -1716,9 +1716,6 @@ int bond_alb_set_mac_address(struct net_ + } + } + +- write_unlock_bh(&bond->curr_slave_lock); +- read_unlock(&bond->lock); +- + if (swap_slave) { + alb_swap_mac_addr(bond, swap_slave, bond->curr_active_slave); + alb_fasten_mac_swap(bond, swap_slave, bond->curr_active_slave); +@@ -1726,16 +1723,15 @@ int bond_alb_set_mac_address(struct net_ + alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr, + bond->alb_info.rlb_enabled); + ++ read_lock(&bond->lock); + alb_send_learning_packets(bond->curr_active_slave, bond_dev->dev_addr); + if (bond->alb_info.rlb_enabled) { + /* inform clients mac address has changed */ + rlb_req_update_slave_clients(bond, bond->curr_active_slave); + } ++ read_unlock(&bond->lock); + } + +- read_lock(&bond->lock); +- write_lock_bh(&bond->curr_slave_lock); +- + return 0; + } + diff --git a/queue-2.6.27/icom-fix-rmmod-crash.patch b/queue-2.6.27/icom-fix-rmmod-crash.patch new file mode 100644 index 00000000000..d2e3617fa5e --- /dev/null +++ b/queue-2.6.27/icom-fix-rmmod-crash.patch @@ -0,0 +1,53 @@ +From 95caa0a9bdaf93607bd0cc8932f53112496f2f22 Mon Sep 17 00:00:00 2001 +From: Breno Leitao +Date: Fri, 22 May 2009 21:30:39 -0300 +Subject: icom: fix rmmod crash + +From: Breno Leitao + +commit 95caa0a9bdaf93607bd0cc8932f53112496f2f22 upstream. + +Actually the icom driver is crashing when is being removed because +the driver is kfreeing the adapter structure before calling +pci_release_regions(), which result in the following error: + + Unable to handle kernel paging request for data at address 0x6b6b6b6b6b6b6d33 + Faulting instruction address: 0xc000000000246b80 + Oops: Kernel access of bad area, sig: 11 [#1] + .... + [c000000012d436a0] [c0000000001002d0] .kfree+0x120/0x34c (unreliable) + [c000000012d43730] [c000000000246d60] .pci_release_selected_regions+0x3c/0x68 + [c000000012d437c0] [d000000002d54700] .icom_kref_release+0xf4/0x118 [icom] + [c000000012d43850] [c000000000232e50] .kref_put+0x74/0x94 + [c000000012d438d0] [d000000002d56c58] .icom_remove+0x40/0xa4 [icom] + [c000000012d43960] [c000000000249e48] .pci_device_remove+0x50/0x90 + [c000000012d439e0] [c0000000002d68d8] .__device_release_driver+0x94/0xd4 + [c000000012d43a70] [c0000000002d7104] .driver_detach+0xf8/0x12c + [c000000012d43b00] [c0000000002d549c] .bus_remove_driver+0xbc/0x11c + [c000000012d43b90] [c0000000002d71dc] .driver_unregister+0x60/0x80 + [c000000012d43c20] [c00000000024a07c] .pci_unregister_driver+0x44/0xe8 + [c000000012d43cb0] [d000000002d56bf4] .icom_exit+0x1c/0x40 [icom] + [c000000012d43d30] [c000000000095fa8] .SyS_delete_module+0x214/0x2a8 + [c000000012d43e30] [c00000000000852c] syscall_exit+0x0/0x40 + +Signed-off-by: Breno Leitao +Cc: Alan Cox +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/serial/icom.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/serial/icom.c ++++ b/drivers/serial/icom.c +@@ -1482,8 +1482,8 @@ static void icom_remove_adapter(struct i + + free_irq(icom_adapter->pci_dev->irq, (void *) icom_adapter); + iounmap(icom_adapter->base_addr); +- icom_free_adapter(icom_adapter); + pci_release_regions(icom_adapter->pci_dev); ++ icom_free_adapter(icom_adapter); + } + + static void icom_kref_release(struct kref *kref) diff --git a/queue-2.6.27/myr10ge-again-fix-lro_gen_skb-alignment.patch b/queue-2.6.27/myr10ge-again-fix-lro_gen_skb-alignment.patch new file mode 100644 index 00000000000..808c01a1e3e --- /dev/null +++ b/queue-2.6.27/myr10ge-again-fix-lro_gen_skb-alignment.patch @@ -0,0 +1,32 @@ +From 6d9fbcfba5b1c83e05a237695ab5fc8b81638fe1 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 15 Apr 2009 02:26:49 -0700 +Subject: myr10ge: again fix lro_gen_skb() alignment + +From: Stanislaw Gruszka + +[ Upstream commit 636d2f68a0814d84de26c021b2c15e3b4ffa29de ] + +Add LRO alignment initially committed in +621544eb8c3beaa859c75850f816dd9b056a00a3 ("[LRO]: fix lro_gen_skb() +alignment") and removed in 0dcffac1a329be69bab0ac604bf7283737108e68 +("myri10ge: add multislices support") during conversion to +multi-slice. + +Signed-off-by: Stanislaw Gruszka +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/myri10ge/myri10ge.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/myri10ge/myri10ge.c ++++ b/drivers/net/myri10ge/myri10ge.c +@@ -2379,6 +2379,7 @@ static int myri10ge_open(struct net_devi + lro_mgr->lro_arr = ss->rx_done.lro_desc; + lro_mgr->get_frag_header = myri10ge_get_frag_header; + lro_mgr->max_aggr = myri10ge_lro_max_pkts; ++ lro_mgr->frag_align_pad = 2; + if (lro_mgr->max_aggr > MAX_SKB_FRAGS) + lro_mgr->max_aggr = MAX_SKB_FRAGS; + diff --git a/queue-2.6.27/net-fix-skb_seq_read-returning-wrong-offset-length-for-page-frag-data.patch b/queue-2.6.27/net-fix-skb_seq_read-returning-wrong-offset-length-for-page-frag-data.patch new file mode 100644 index 00000000000..62a799802d5 --- /dev/null +++ b/queue-2.6.27/net-fix-skb_seq_read-returning-wrong-offset-length-for-page-frag-data.patch @@ -0,0 +1,33 @@ +From 04184d5545555db238df7ac550dd48571f65220f Mon Sep 17 00:00:00 2001 +From: Thomas Chenault +Date: Mon, 18 May 2009 21:43:27 -0700 +Subject: net: fix skb_seq_read returning wrong offset/length for page frag data + +From: Thomas Chenault + +[ Upstream commit 995b337952cdf7e05d288eede580257b632a8343 ] + +When called with a consumed value that is less than skb_headlen(skb) +bytes into a page frag, skb_seq_read() incorrectly returns an +offset/length relative to skb->data. Ensure that data which should come +from a page frag does. + +Signed-off-by: Thomas Chenault +Tested-by: Shyam Iyer +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/skbuff.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -1992,7 +1992,7 @@ unsigned int skb_seq_read(unsigned int c + next_skb: + block_limit = skb_headlen(st->cur_skb) + st->stepped_offset; + +- if (abs_offset < block_limit) { ++ if (abs_offset < block_limit && !st->frag_data) { + *data = st->cur_skb->data + (abs_offset - st->stepped_offset); + return block_limit - abs_offset; + } diff --git a/queue-2.6.27/nfs-fix-nfs-v4-client-handling-of-may_exec-in-nfs_permission.patch b/queue-2.6.27/nfs-fix-nfs-v4-client-handling-of-may_exec-in-nfs_permission.patch new file mode 100644 index 00000000000..77b5967a4c0 --- /dev/null +++ b/queue-2.6.27/nfs-fix-nfs-v4-client-handling-of-may_exec-in-nfs_permission.patch @@ -0,0 +1,42 @@ +From 7ee2cb7f32b299c2b06a31fde155457203e4b7dd Mon Sep 17 00:00:00 2001 +From: Frank Filz +Date: Mon, 18 May 2009 17:41:40 -0400 +Subject: nfs: Fix NFS v4 client handling of MAY_EXEC in nfs_permission. + +From: Frank Filz + +commit 7ee2cb7f32b299c2b06a31fde155457203e4b7dd upstream. + +The problem is that permission checking is skipped if atomic open is +possible, but when exec opens a file, it just opens it O_READONLY which +means EXEC permission will not be checked at that time. + +This problem is observed by the following sequence (executed as root): + + mount -t nfs4 server:/ /mnt4 + echo "ls" >/mnt4/foo + chmod 744 /mnt4/foo + su guest -c "mnt4/foo" + +Signed-off-by: Frank Filz +Signed-off-by: Trond Myklebust +Tested-by: Eugene Teo +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/dir.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/nfs/dir.c ++++ b/fs/nfs/dir.c +@@ -1925,7 +1925,8 @@ int nfs_permission(struct inode *inode, + case S_IFREG: + /* NFSv4 has atomic_open... */ + if (nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN) +- && (mask & MAY_OPEN)) ++ && (mask & MAY_OPEN) ++ && !(mask & MAY_EXEC)) + goto out; + break; + case S_IFDIR: diff --git a/queue-2.6.27/pktgen-do-not-access-flows-beyond-its-length.patch b/queue-2.6.27/pktgen-do-not-access-flows-beyond-its-length.patch new file mode 100644 index 00000000000..df21a564529 --- /dev/null +++ b/queue-2.6.27/pktgen-do-not-access-flows-beyond-its-length.patch @@ -0,0 +1,31 @@ +From 70af28cffce3a384242c90a51e368f3e0c7bbb05 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Thu, 21 May 2009 15:07:12 -0700 +Subject: pktgen: do not access flows[] beyond its length + +From: Florian Westphal + +[ Upstream commit 5b5f792a6a9a2f9ae812d151ed621f72e99b1725 ] + +typo -- pkt_dev->nflows is for stats only, the number of concurrent +flows is stored in cflows. + +Reported-By: Vladimir Ivashchenko +Signed-off-by: Florian Westphal +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/pktgen.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/core/pktgen.c ++++ b/net/core/pktgen.c +@@ -2449,7 +2449,7 @@ static inline void free_SAs(struct pktge + if (pkt_dev->cflows) { + /* let go of the SAs if we have them */ + int i = 0; +- for (; i < pkt_dev->nflows; i++){ ++ for (; i < pkt_dev->cflows; i++) { + struct xfrm_state *x = pkt_dev->flows[i].x; + if (x) { + xfrm_state_put(x); diff --git a/queue-2.6.27/series b/queue-2.6.27/series new file mode 100644 index 00000000000..be10adfae5f --- /dev/null +++ b/queue-2.6.27/series @@ -0,0 +1,16 @@ +icom-fix-rmmod-crash.patch +nfs-fix-nfs-v4-client-handling-of-may_exec-in-nfs_permission.patch +tpm-get_event_name-stack-corruption.patch +sparc64-fix-smp_callin-locking.patch +sparc-fix-bus-type-probing-for-esp-and-le-devices.patch +sparc64-fix-mm-refcount-check-in-smp_flush_tlb_pending.patch +sparc64-flush-tlb-before-releasing-pages.patch +sparc64-fix-crash-with-proc-iomem.patch +sparc64-fix-lost-interrupts-on-sun4u.patch +sparc64-reschedule-kgdb-capture-to-a-software-interrupt.patch +bonding-fix-alb-mode-locking-regression.patch +vlan-macvlan-fix-null-pointer-dereferences-in-ethtool-handlers.patch +myr10ge-again-fix-lro_gen_skb-alignment.patch +pktgen-do-not-access-flows-beyond-its-length.patch +net-fix-skb_seq_read-returning-wrong-offset-length-for-page-frag-data.patch +tcp-fix-2-iw-selection.patch diff --git a/queue-2.6.27/sparc-fix-bus-type-probing-for-esp-and-le-devices.patch b/queue-2.6.27/sparc-fix-bus-type-probing-for-esp-and-le-devices.patch new file mode 100644 index 00000000000..423b9cf0da5 --- /dev/null +++ b/queue-2.6.27/sparc-fix-bus-type-probing-for-esp-and-le-devices.patch @@ -0,0 +1,91 @@ +From a11411e1ce08275a202214c50b6ce028a5c13ac2 Mon Sep 17 00:00:00 2001 +From: David S. Miller +Date: Tue, 26 May 2009 15:56:18 -0700 +Subject: sparc: Fix bus type probing for ESP and LE devices. + +From: David S. Miller + +If there is a dummy "espdma" or "ledma" parent device above ESP scsi +or LE ethernet device nodes, we have to match the bus as SBUS. + +Otherwise the address and size cell counts are wrong and we don't +calculate the final physical device resource values correctly at all. + +Commit 5280267c1dddb8d413595b87dc406624bb497946 ("sparc: Fix handling +of LANCE and ESP parent nodes in of_device.c") was meant to fix this +problem, but that only influences the inner loop of +build_device_resources(). We need this logic to also kick in at the +beginning of build_device_resources() as well, when we make the first +attempt to determine the device's immediate parent bus type for 'reg' +property element extraction. + +Based almost entirely upon a patch by Friedrich Oslage. + +Tested-by: Meelis Roos +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + arch/sparc/kernel/of_device.c | 21 +++++++++++++++++++-- + arch/sparc64/kernel/of_device.c | 21 +++++++++++++++++++-- + 2 files changed, 38 insertions(+), 4 deletions(-) + +--- a/arch/sparc64/kernel/of_device.c ++++ b/arch/sparc64/kernel/of_device.c +@@ -278,8 +278,25 @@ static unsigned long of_bus_pci_get_flag + + static int of_bus_sbus_match(struct device_node *np) + { +- return !strcmp(np->name, "sbus") || +- !strcmp(np->name, "sbi"); ++ struct device_node *dp = np; ++ ++ while (dp) { ++ if (!strcmp(dp->name, "sbus") || ++ !strcmp(dp->name, "sbi")) ++ return 1; ++ ++ /* Have a look at use_1to1_mapping(). We're trying ++ * to match SBUS if that's the top-level bus and we ++ * don't have some intervening real bus that provides ++ * ranges based translations. ++ */ ++ if (of_find_property(dp, "ranges", NULL) != NULL) ++ break; ++ ++ dp = dp->parent; ++ } ++ ++ return 0; + } + + static void of_bus_sbus_count_cells(struct device_node *child, +--- a/arch/sparc/kernel/of_device.c ++++ b/arch/sparc/kernel/of_device.c +@@ -223,8 +223,25 @@ static unsigned long of_bus_pci_get_flag + + static int of_bus_sbus_match(struct device_node *np) + { +- return !strcmp(np->name, "sbus") || +- !strcmp(np->name, "sbi"); ++ struct device_node *dp = np; ++ ++ while (dp) { ++ if (!strcmp(dp->name, "sbus") || ++ !strcmp(dp->name, "sbi")) ++ return 1; ++ ++ /* Have a look at use_1to1_mapping(). We're trying ++ * to match SBUS if that's the top-level bus and we ++ * don't have some intervening real bus that provides ++ * ranges based translations. ++ */ ++ if (of_find_property(dp, "ranges", NULL) != NULL) ++ break; ++ ++ dp = dp->parent; ++ } ++ ++ return 0; + } + + static void of_bus_sbus_count_cells(struct device_node *child, diff --git a/queue-2.6.27/sparc64-fix-crash-with-proc-iomem.patch b/queue-2.6.27/sparc64-fix-crash-with-proc-iomem.patch new file mode 100644 index 00000000000..e35b000da33 --- /dev/null +++ b/queue-2.6.27/sparc64-fix-crash-with-proc-iomem.patch @@ -0,0 +1,39 @@ +From 9f718c834a458ef9215736a4da9e409bfe9df1c4 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Tue, 26 May 2009 16:00:12 -0700 +Subject: sparc64: Fix crash with /proc/iomem + +From: Mikulas Patocka + + +[ Upstream commit 192d7a4667c6d11d1a174ec4cad9a3c5d5f9043c ] + +When you compile kernel on Sparc64 with heap memory checking and type +"cat /proc/iomem", you get a crash, because pointers in struct +resource are uninitialized. + +Most code fills struct resource with zeros, so I assume that it is +responsibility of the caller of request_resource to initialized it, +not the responsibility of request_resource functuion. + +After 2.6.29 is out, there could be a check for uninitialized fields +added to request_resource to avoid crashes like this. + +Signed-off-by: Mikulas Patocka +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + arch/sparc64/kernel/pci_common.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/sparc64/kernel/pci_common.c ++++ b/arch/sparc64/kernel/pci_common.c +@@ -368,7 +368,7 @@ static void pci_register_iommu_region(st + const u32 *vdma = of_get_property(pbm->prom_node, "virtual-dma", NULL); + + if (vdma) { +- struct resource *rp = kmalloc(sizeof(*rp), GFP_KERNEL); ++ struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL); + + if (!rp) { + prom_printf("Cannot allocate IOMMU resource.\n"); diff --git a/queue-2.6.27/sparc64-fix-lost-interrupts-on-sun4u.patch b/queue-2.6.27/sparc64-fix-lost-interrupts-on-sun4u.patch new file mode 100644 index 00000000000..a2b35ac7da0 --- /dev/null +++ b/queue-2.6.27/sparc64-fix-lost-interrupts-on-sun4u.patch @@ -0,0 +1,91 @@ +From 4aec51deee6101e9d6c3dae59e19855603f47fa5 Mon Sep 17 00:00:00 2001 +From: David S. Miller +Date: Wed, 4 Mar 2009 14:43:47 -0800 +Subject: sparc64: Fix lost interrupts on sun4u. + +From: David S. Miller + +[ Upstream commit d0cac39e4ec8097e4c7099d291b1fdcc0fe56b58 ] + +Based upon a report by Meelis Roos. + +Sparc64 SBUS and PCI controllers use a combination of IMAP and ICLR +registers to manage device interrupts. + +The IMAP register contains the "valid" enable bit as well as CPU +targetting information. Whereas the ICLR register is written with +zero at the end of handling an interrupt to reset the state machine +for that interrupt to IDLE so it can be sent again. + +For PCI slot and SBUS slot devices we can have multiple interrupts +sharing the same IMAP register. There are individual ICLR registers +but only one IMAP register for managing those. + +We represent each shared case with individual virtual IRQs so the +generic IRQ layer thinks there is only one user of the IRQ instance. + +In such shared IMAP cases this is wrong, so if there are multiple +active users then a free_irq() call will prematurely turn off the +interrupt by clearing the Valid bit in the IMAP register even though +there are other active users. + +Fix this by simply doing nothing in sun4u_disable_irq() and checking +IRQF_DISABLED during IRQ dispatch. + +This situation doesn't exist in the hypervisor sun4v cases, so I left +those alone. + +Tested-by: Meelis Roos +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + arch/sparc64/kernel/irq.c | 29 +++++++++++++++++++---------- + 1 file changed, 19 insertions(+), 10 deletions(-) + +--- a/arch/sparc64/kernel/irq.c ++++ b/arch/sparc64/kernel/irq.c +@@ -318,17 +318,25 @@ static void sun4u_set_affinity(unsigned + sun4u_irq_enable(virt_irq); + } + ++/* Don't do anything. The desc->status check for IRQ_DISABLED in ++ * handler_irq() will skip the handler call and that will leave the ++ * interrupt in the sent state. The next ->enable() call will hit the ++ * ICLR register to reset the state machine. ++ * ++ * This scheme is necessary, instead of clearing the Valid bit in the ++ * IMAP register, to handle the case of IMAP registers being shared by ++ * multiple INOs (and thus ICLR registers). Since we use a different ++ * virtual IRQ for each shared IMAP instance, the generic code thinks ++ * there is only one user so it prematurely calls ->disable() on ++ * free_irq(). ++ * ++ * We have to provide an explicit ->disable() method instead of using ++ * NULL to get the default. The reason is that if the generic code ++ * sees that, it also hooks up a default ->shutdown method which ++ * invokes ->mask() which we do not want. See irq_chip_set_defaults(). ++ */ + static void sun4u_irq_disable(unsigned int virt_irq) + { +- struct irq_handler_data *data = get_irq_chip_data(virt_irq); +- +- if (likely(data)) { +- unsigned long imap = data->imap; +- unsigned long tmp = upa_readq(imap); +- +- tmp &= ~IMAP_VALID; +- upa_writeq(tmp, imap); +- } + } + + static void sun4u_irq_eoi(unsigned int virt_irq) +@@ -739,7 +747,8 @@ void handler_irq(int irq, struct pt_regs + + desc = irq_desc + virt_irq; + +- desc->handle_irq(virt_irq, desc); ++ if (!(desc->status & IRQ_DISABLED)) ++ desc->handle_irq(virt_irq, desc); + + bucket_pa = next_pa; + } diff --git a/queue-2.6.27/sparc64-fix-mm-refcount-check-in-smp_flush_tlb_pending.patch b/queue-2.6.27/sparc64-fix-mm-refcount-check-in-smp_flush_tlb_pending.patch new file mode 100644 index 00000000000..9cd6561f123 --- /dev/null +++ b/queue-2.6.27/sparc64-fix-mm-refcount-check-in-smp_flush_tlb_pending.patch @@ -0,0 +1,70 @@ +From 251bc24766f8f53ef8ba61228dfca1398bd9dc85 Mon Sep 17 00:00:00 2001 +From: David S. Miller +Date: Fri, 27 Mar 2009 01:09:17 -0700 +Subject: sparc64: Fix MM refcount check in smp_flush_tlb_pending(). + +From: David S. Miller + +[ Upstream commit f9384d41c02408dd404aa64d66d0ef38adcf6479 ] + +As explained by Benjamin Herrenschmidt: + +> CPU 0 is running the context, task->mm == task->active_mm == your +> context. The CPU is in userspace happily churning things. +> +> CPU 1 used to run it, not anymore, it's now running fancyfsd which +> is a kernel thread, but current->active_mm still points to that +> same context. +> +> Because there's only one "real" user, mm_users is 1 (but mm_count is +> elevated, it's just that the presence on CPU 1 as active_mm has no +> effect on mm_count(). +> +> At this point, fancyfsd decides to invalidate a mapping currently mapped +> by that context, for example because a networked file has changed +> remotely or something like that, using unmap_mapping_ranges(). +> +> So CPU 1 goes into the zapping code, which eventually ends up calling +> flush_tlb_pending(). Your test will succeed, as current->active_mm is +> indeed the target mm for the flush, and mm_users is indeed 1. So you +> will -not- send an IPI to the other CPU, and CPU 0 will continue happily +> accessing the pages that should have been unmapped. + +To fix this problem, check ->mm instead of ->active_mm, and this +means: + +> So if you test current->mm, you effectively account for mm_users == 1, +> so the only way the mm can be active on another processor is as a lazy +> mm for a kernel thread. So your test should work properly as long +> as you don't have a HW that will do speculative TLB reloads into the +> TLB on that other CPU (and even if you do, you flush-on-switch-in should +> get rid of any crap here). + +And therefore we should be OK. + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + arch/sparc64/kernel/smp.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/sparc64/kernel/smp.c ++++ b/arch/sparc64/kernel/smp.c +@@ -1031,7 +1031,7 @@ void smp_fetch_global_regs(void) + * If the address space is non-shared (ie. mm->count == 1) we avoid + * cross calls when we want to flush the currently running process's + * tlb state. This is done by clearing all cpu bits except the current +- * processor's in current->active_mm->cpu_vm_mask and performing the ++ * processor's in current->mm->cpu_vm_mask and performing the + * flush locally only. This will force any subsequent cpus which run + * this task to flush the context from the local tlb if the process + * migrates to another cpu (again). +@@ -1074,7 +1074,7 @@ void smp_flush_tlb_pending(struct mm_str + u32 ctx = CTX_HWBITS(mm->context); + int cpu = get_cpu(); + +- if (mm == current->active_mm && atomic_read(&mm->mm_users) == 1) ++ if (mm == current->mm && atomic_read(&mm->mm_users) == 1) + mm->cpu_vm_mask = cpumask_of_cpu(cpu); + else + smp_cross_call_masked(&xcall_flush_tlb_pending, diff --git a/queue-2.6.27/sparc64-fix-smp_callin-locking.patch b/queue-2.6.27/sparc64-fix-smp_callin-locking.patch new file mode 100644 index 00000000000..33f320da459 --- /dev/null +++ b/queue-2.6.27/sparc64-fix-smp_callin-locking.patch @@ -0,0 +1,34 @@ +From 4eb1996bb99d07a6e8286dda0f2ea759abe9f08a Mon Sep 17 00:00:00 2001 +From: David S. Miller +Date: Wed, 8 Apr 2009 21:06:35 -0700 +Subject: sparc64: Fix smp_callin() locking. + +From: David S. Miller + +[ Upstream commit 8e255baa449df3049a8827a7f1f4f12b6921d0d1 ] + +Interrupts must be disabled when taking the IPI lock. + +Caught by lockdep. + +Reported-by: Meelis Roos +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + arch/sparc64/kernel/smp.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/sparc64/kernel/smp.c ++++ b/arch/sparc64/kernel/smp.c +@@ -118,9 +118,9 @@ void __cpuinit smp_callin(void) + while (!cpu_isset(cpuid, smp_commenced_mask)) + rmb(); + +- ipi_call_lock(); ++ ipi_call_lock_irq(); + cpu_set(cpuid, cpu_online_map); +- ipi_call_unlock(); ++ ipi_call_unlock_irq(); + + /* idle thread is expected to have preempt disabled */ + preempt_disable(); diff --git a/queue-2.6.27/sparc64-flush-tlb-before-releasing-pages.patch b/queue-2.6.27/sparc64-flush-tlb-before-releasing-pages.patch new file mode 100644 index 00000000000..0e8fc99f7ef --- /dev/null +++ b/queue-2.6.27/sparc64-flush-tlb-before-releasing-pages.patch @@ -0,0 +1,40 @@ +From ac01c015a520e919907dd88af0476a89f3d018cd Mon Sep 17 00:00:00 2001 +From: David S. Miller +Date: Thu, 26 Mar 2009 01:28:53 -0700 +Subject: sparc64: Flush TLB before releasing pages. + +From: David S. Miller + +[ Upstream commit 86ee79c3dbd48d7430fd81edc1da3516c9f6dabc ] + +tlb_flush_mmu() needs to flush pending TLB entries before +processing the mmu_gather ->pages list. + +Noticed by Benjamin Herrenschmidt. + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + arch/sparc/include/asm/tlb_64.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/sparc/include/asm/tlb_64.h ++++ b/arch/sparc/include/asm/tlb_64.h +@@ -58,6 +58,8 @@ static inline struct mmu_gather *tlb_gat + static inline void tlb_flush_mmu(struct mmu_gather *mp) + { + if (mp->need_flush) { ++ if (!mp->fullmm) ++ flush_tlb_pending(); + free_pages_and_swap_cache(mp->pages, mp->pages_nr); + mp->pages_nr = 0; + mp->need_flush = 0; +@@ -78,8 +80,6 @@ static inline void tlb_finish_mmu(struct + + if (mp->fullmm) + mp->fullmm = 0; +- else +- flush_tlb_pending(); + + /* keep the page table cache within bounds */ + check_pgt_cache(); diff --git a/queue-2.6.27/sparc64-reschedule-kgdb-capture-to-a-software-interrupt.patch b/queue-2.6.27/sparc64-reschedule-kgdb-capture-to-a-software-interrupt.patch new file mode 100644 index 00000000000..20f48a01d11 --- /dev/null +++ b/queue-2.6.27/sparc64-reschedule-kgdb-capture-to-a-software-interrupt.patch @@ -0,0 +1,92 @@ +From 831df31d3de4d524e35ba0c2403f78ce5c57a893 Mon Sep 17 00:00:00 2001 +From: David S. Miller +Date: Tue, 26 May 2009 19:00:54 -0700 +Subject: sparc64: Reschedule KGDB capture to a software interrupt. + +From: David S. Miller + +[ Upstream commit 42cc77c861e8e850e86252bb5b1e12e006261973 ] + +Otherwise it might interrupt switch_to() midstream and use +half-cooked register window state. + +Reported-by: Chris Torek +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + arch/sparc/include/asm/pil.h | 1 + + arch/sparc64/kernel/kgdb.c | 2 +- + arch/sparc64/kernel/ttable.S | 8 +++++++- + arch/sparc64/mm/ultra.S | 24 ++---------------------- + 4 files changed, 11 insertions(+), 24 deletions(-) + +--- a/arch/sparc64/kernel/kgdb.c ++++ b/arch/sparc64/kernel/kgdb.c +@@ -108,7 +108,7 @@ void gdb_regs_to_pt_regs(unsigned long * + } + + #ifdef CONFIG_SMP +-void smp_kgdb_capture_client(struct pt_regs *regs) ++void smp_kgdb_capture_client(int irq, struct pt_regs *regs) + { + unsigned long flags; + +--- a/arch/sparc64/kernel/ttable.S ++++ b/arch/sparc64/kernel/ttable.S +@@ -63,7 +63,13 @@ tl0_irq6: TRAP_IRQ(smp_call_function_sin + #else + tl0_irq6: BTRAP(0x46) + #endif +-tl0_irq7: BTRAP(0x47) BTRAP(0x48) BTRAP(0x49) ++tl0_irq7: BTRAP(0x47) ++#ifdef CONFIG_KGDB ++tl0_irq8: TRAP_IRQ(smp_kgdb_capture_client, 8) ++#else ++tl0_irq8: BTRAP(0x48) ++#endif ++tl0_irq9: BTRAP(0x49) + tl0_irq10: BTRAP(0x4a) BTRAP(0x4b) BTRAP(0x4c) BTRAP(0x4d) + tl0_irq14: TRAP_IRQ(timer_interrupt, 14) + tl0_irq15: TRAP_IRQ(handler_irq, 15) +--- a/arch/sparc64/mm/ultra.S ++++ b/arch/sparc64/mm/ultra.S +@@ -681,28 +681,8 @@ xcall_new_mmu_context_version: + #ifdef CONFIG_KGDB + .globl xcall_kgdb_capture + xcall_kgdb_capture: +-661: rdpr %pstate, %g2 +- wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate +- .section .sun4v_2insn_patch, "ax" +- .word 661b +- nop +- nop +- .previous +- +- rdpr %pil, %g2 +- wrpr %g0, 15, %pil +- sethi %hi(109f), %g7 +- ba,pt %xcc, etrap_irq +-109: or %g7, %lo(109b), %g7 +-#ifdef CONFIG_TRACE_IRQFLAGS +- call trace_hardirqs_off +- nop +-#endif +- call smp_kgdb_capture_client +- add %sp, PTREGS_OFF, %o0 +- /* Has to be a non-v9 branch due to the large distance. */ +- ba rtrap_xcall +- ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 ++ wr %g0, (1 << PIL_KGDB_CAPTURE), %set_softint ++ retry + #endif + + #endif /* CONFIG_SMP */ +--- a/arch/sparc/include/asm/pil.h ++++ b/arch/sparc/include/asm/pil.h +@@ -18,5 +18,6 @@ + #define PIL_SMP_CTX_NEW_VERSION 4 + #define PIL_DEVICE_IRQ 5 + #define PIL_SMP_CALL_FUNC_SNGL 6 ++#define PIL_KGDB_CAPTURE 8 + + #endif /* !(_SPARC64_PIL_H) */ diff --git a/queue-2.6.27/tcp-fix-2-iw-selection.patch b/queue-2.6.27/tcp-fix-2-iw-selection.patch new file mode 100644 index 00000000000..d004f2b260f --- /dev/null +++ b/queue-2.6.27/tcp-fix-2-iw-selection.patch @@ -0,0 +1,38 @@ +From 178e7dc61292f729d7f31ffe50a2218b69af48c8 Mon Sep 17 00:00:00 2001 +From: Ilpo Järvinen +Date: Tue, 26 May 2009 15:51:35 -0700 +Subject: tcp: fix >2 iw selection + +From: Ilpo Järvinen + +[ Upstream commit 86bcebafc5e7f5163ccf828792fe694b112ed6fa ] + +A long-standing feature in tcp_init_metrics() is such that +any of its goto reset prevents call to tcp_init_cwnd(). + +Signed-off-by: Ilpo Järvinen +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_input.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -931,6 +931,8 @@ static void tcp_init_metrics(struct sock + tcp_bound_rto(sk); + if (inet_csk(sk)->icsk_rto < TCP_TIMEOUT_INIT && !tp->rx_opt.saw_tstamp) + goto reset; ++ ++cwnd: + tp->snd_cwnd = tcp_init_cwnd(tp, dst); + tp->snd_cwnd_stamp = tcp_time_stamp; + return; +@@ -945,6 +947,7 @@ reset: + tp->mdev = tp->mdev_max = tp->rttvar = TCP_TIMEOUT_INIT; + inet_csk(sk)->icsk_rto = TCP_TIMEOUT_INIT; + } ++ goto cwnd; + } + + static void tcp_update_reordering(struct sock *sk, const int metric, diff --git a/queue-2.6.27/tpm-get_event_name-stack-corruption.patch b/queue-2.6.27/tpm-get_event_name-stack-corruption.patch new file mode 100644 index 00000000000..39050664a64 --- /dev/null +++ b/queue-2.6.27/tpm-get_event_name-stack-corruption.patch @@ -0,0 +1,36 @@ +From fbaa58696cef848de818768783ef185bd3f05158 Mon Sep 17 00:00:00 2001 +From: Eric Paris +Date: Wed, 13 May 2009 12:50:40 -0400 +Subject: TPM: get_event_name stack corruption + +From: Eric Paris + +commit fbaa58696cef848de818768783ef185bd3f05158 upstream. + +get_event_name uses sprintf to fill a buffer declared on the stack. It fills +the buffer 2 bytes at a time. What the code doesn't take into account is that +sprintf(buf, "%02x", data) actually writes 3 bytes. 2 bytes for the data and +then it nul terminates the string. Since we declare buf to be 40 characters +long and then we write 40 bytes of data into buf sprintf is going to write 41 +characters. The fix is to leave room in buf for the nul terminator. + +Signed-off-by: Eric Paris +Signed-off-by: James Morris +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/tpm/tpm_bios.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/char/tpm/tpm_bios.c ++++ b/drivers/char/tpm/tpm_bios.c +@@ -214,7 +214,8 @@ static int get_event_name(char *dest, st + unsigned char * event_entry) + { + const char *name = ""; +- char data[40] = ""; ++ /* 41 so there is room for 40 data and 1 nul */ ++ char data[41] = ""; + int i, n_len = 0, d_len = 0; + struct tcpa_pc_event *pc_event; + diff --git a/queue-2.6.27/vlan-macvlan-fix-null-pointer-dereferences-in-ethtool-handlers.patch b/queue-2.6.27/vlan-macvlan-fix-null-pointer-dereferences-in-ethtool-handlers.patch new file mode 100644 index 00000000000..47115911fde --- /dev/null +++ b/queue-2.6.27/vlan-macvlan-fix-null-pointer-dereferences-in-ethtool-handlers.patch @@ -0,0 +1,32 @@ +From 31caa9b70685eb91f72e8e051cc3b7540689f473 Mon Sep 17 00:00:00 2001 +From: Patrick McHardy +Date: Tue, 26 May 2009 15:49:11 -0700 +Subject: vlan/macvlan: fix NULL pointer dereferences in ethtool handlers + +From: Patrick McHardy + +[ Upstream commit 7816a0a862d851d0b05710e7d94bfe390f3180e2 ] + +Check whether the underlying device provides a set of ethtool ops before +checking for individual handlers to avoid NULL pointer dereferences. + +Reported-by: Art van Breemen +Signed-off-by: Patrick McHardy +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/macvlan.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -328,7 +328,8 @@ static u32 macvlan_ethtool_get_rx_csum(s + const struct macvlan_dev *vlan = netdev_priv(dev); + struct net_device *lowerdev = vlan->lowerdev; + +- if (lowerdev->ethtool_ops->get_rx_csum == NULL) ++ if (lowerdev->ethtool_ops == NULL || ++ lowerdev->ethtool_ops->get_rx_csum == NULL) + return 0; + return lowerdev->ethtool_ops->get_rx_csum(lowerdev); + }