From: Greg Kroah-Hartman Date: Wed, 29 Apr 2009 02:09:44 +0000 (-0700) Subject: more .27 patches X-Git-Tag: v2.6.27.22~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a5937bea6a4e92ff8c87d8119ae013de8a6bc879;p=thirdparty%2Fkernel%2Fstable-queue.git more .27 patches --- diff --git a/queue-2.6.27/mm-check-for-no-mmaps-in-exit_mmap.patch b/queue-2.6.27/mm-check-for-no-mmaps-in-exit_mmap.patch new file mode 100644 index 00000000000..430920415d6 --- /dev/null +++ b/queue-2.6.27/mm-check-for-no-mmaps-in-exit_mmap.patch @@ -0,0 +1,43 @@ +From dcd4a049b9751828c516c59709f3fdf50436df85 Mon Sep 17 00:00:00 2001 +From: Johannes Weiner +Date: Tue, 6 Jan 2009 14:40:31 -0800 +Subject: mm: check for no mmaps in exit_mmap() + +From: Johannes Weiner + +commit dcd4a049b9751828c516c59709f3fdf50436df85 upstream. + +When dup_mmap() ooms we can end up with mm->mmap == NULL. The error +path does mmput() and unmap_vmas() gets a NULL vma which it +dereferences. + +In exit_mmap() there is nothing to do at all for this case, we can +cancel the callpath right there. + +[akpm@linux-foundation.org: add sorely-needed comment] +Signed-off-by: Johannes Weiner +Reported-by: Akinobu Mita +Cc: Nick Piggin +Cc: Hugh Dickins +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Reported-by: Kir Kolyshkin +Tested-by: Kir Kolyshkin +Signed-off-by: Greg Kroah-Hartman + +--- + mm/mmap.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -2068,6 +2068,9 @@ void exit_mmap(struct mm_struct *mm) + arch_exit_mmap(mm); + mmu_notifier_release(mm); + ++ if (!mm->mmap) /* Can happen if dup_mmap() received an OOM */ ++ return; ++ + lru_add_drain(); + flush_cache_mm(mm); + tlb = tlb_gather_mmu(mm, 1); diff --git a/queue-2.6.27/powerpc-sanitize-stack-pointer-in-signal-handling-code.patch b/queue-2.6.27/powerpc-sanitize-stack-pointer-in-signal-handling-code.patch new file mode 100644 index 00000000000..83d09150a9e --- /dev/null +++ b/queue-2.6.27/powerpc-sanitize-stack-pointer-in-signal-handling-code.patch @@ -0,0 +1,125 @@ +From jwboyer@linux.vnet.ibm.com Tue Apr 28 19:08:48 2009 +From: Josh Boyer +Date: Tue, 28 Apr 2009 11:11:57 -0400 +Subject: powerpc: Sanitize stack pointer in signal handling code +To: stable@kernel.org +Cc: benh@kernel.crashing.org +Message-ID: <20090428151157.GA5281@yoda.jdub.homelinux.org> + +From: Josh Boyer + +This has been backported to 2.6.27.x from commit efbda86098 in Linus' tree. + +On powerpc64 machines running 32-bit userspace, we can get garbage bits in the +stack pointer passed into the kernel. Most places handle this correctly, but +the signal handling code uses the passed value directly for allocating signal +stack frames. + +This fixes the issue by introducing a get_clean_sp function that returns a +sanitized stack pointer. For 32-bit tasks on a 64-bit kernel, the stack +pointer is masked correctly. In all other cases, the stack pointer is simply +returned. + +Additionally, we pass an 'is_32' parameter to get_sigframe now in order to +get the properly sanitized stack. The callers are know to be 32 or 64-bit +statically. + +Signed-off-by: Josh Boyer +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/include/asm/processor.h | 19 +++++++++++++++++++ + arch/powerpc/kernel/signal.c | 4 ++-- + arch/powerpc/kernel/signal.h | 2 +- + arch/powerpc/kernel/signal_32.c | 4 ++-- + arch/powerpc/kernel/signal_64.c | 2 +- + 5 files changed, 25 insertions(+), 6 deletions(-) + +--- a/arch/powerpc/include/asm/processor.h ++++ b/arch/powerpc/include/asm/processor.h +@@ -309,6 +309,25 @@ static inline void prefetchw(const void + #define HAVE_ARCH_PICK_MMAP_LAYOUT + #endif + ++#ifdef CONFIG_PPC64 ++static inline unsigned long get_clean_sp(struct pt_regs *regs, int is_32) ++{ ++ unsigned long sp; ++ ++ if (is_32) ++ sp = regs->gpr[1] & 0x0ffffffffUL; ++ else ++ sp = regs->gpr[1]; ++ ++ return sp; ++} ++#else ++static inline unsigned long get_clean_sp(struct pt_regs *regs, int is_32) ++{ ++ return regs->gpr[1]; ++} ++#endif ++ + #endif /* __KERNEL__ */ + #endif /* __ASSEMBLY__ */ + #endif /* _ASM_POWERPC_PROCESSOR_H */ +--- a/arch/powerpc/kernel/signal_32.c ++++ b/arch/powerpc/kernel/signal_32.c +@@ -836,7 +836,7 @@ int handle_rt_signal32(unsigned long sig + + /* Set up Signal Frame */ + /* Put a Real Time Context onto stack */ +- rt_sf = get_sigframe(ka, regs, sizeof(*rt_sf)); ++ rt_sf = get_sigframe(ka, regs, sizeof(*rt_sf), 1); + addr = rt_sf; + if (unlikely(rt_sf == NULL)) + goto badframe; +@@ -1170,7 +1170,7 @@ int handle_signal32(unsigned long sig, s + unsigned long newsp = 0; + + /* Set up Signal Frame */ +- frame = get_sigframe(ka, regs, sizeof(*frame)); ++ frame = get_sigframe(ka, regs, sizeof(*frame), 1); + if (unlikely(frame == NULL)) + goto badframe; + sc = (struct sigcontext __user *) &frame->sctx; +--- a/arch/powerpc/kernel/signal_64.c ++++ b/arch/powerpc/kernel/signal_64.c +@@ -404,7 +404,7 @@ int handle_rt_signal64(int signr, struct + unsigned long newsp = 0; + long err = 0; + +- frame = get_sigframe(ka, regs, sizeof(*frame)); ++ frame = get_sigframe(ka, regs, sizeof(*frame), 0); + if (unlikely(frame == NULL)) + goto badframe; + +--- a/arch/powerpc/kernel/signal.c ++++ b/arch/powerpc/kernel/signal.c +@@ -26,12 +26,12 @@ int show_unhandled_signals = 0; + * Allocate space for the signal frame + */ + void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, +- size_t frame_size) ++ size_t frame_size, int is_32) + { + unsigned long oldsp, newsp; + + /* Default to using normal stack */ +- oldsp = regs->gpr[1]; ++ oldsp = get_clean_sp(regs, is_32); + + /* Check for alt stack */ + if ((ka->sa.sa_flags & SA_ONSTACK) && +--- a/arch/powerpc/kernel/signal.h ++++ b/arch/powerpc/kernel/signal.h +@@ -13,7 +13,7 @@ + #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) + + extern void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, +- size_t frame_size); ++ size_t frame_size, int is_32); + extern void restore_sigmask(sigset_t *set); + + extern int handle_signal32(unsigned long sig, struct k_sigaction *ka, diff --git a/queue-2.6.27/r8169-don-t-update-statistics-counters-when-interface-is-down.patch b/queue-2.6.27/r8169-don-t-update-statistics-counters-when-interface-is-down.patch new file mode 100644 index 00000000000..38a4bd1efff --- /dev/null +++ b/queue-2.6.27/r8169-don-t-update-statistics-counters-when-interface-is-down.patch @@ -0,0 +1,184 @@ +From romieu@fr.zoreil.com Tue Apr 28 19:04:48 2009 +From: Francois Romieu +Date: Thu, 16 Apr 2009 23:33:00 +0200 +Subject: r8169: Don't update statistics counters when interface is down +To: Greg KH +Message-ID: <20090416213300.GA26270@electric-eye.fr.zoreil.com> +Content-Disposition: inline + +From: Francois Romieu + +Upstream as 355423d0849f4506bc71ab2738d38cb74429aaef (post 2.6.28). + +Some Realtek chips (RTL8169sb/8110sb in my case) are unable to retrieve +ethtool statistics when the interface is down. The process stays in +endless loop in rtl8169_get_ethtool_stats. This is because these chips +need to have receiver enabled (CmdRxEnb bit in ChipCmd register) that is +cleared when the interface is going down. It's better to update statistics +only when the interface is up and otherwise return copy of statistics +grabbed when the interface was up (in rtl8169_close). + +It is interesting that PCI-E NICs (like 8168b/8111b...) are not affected. + +Signed-off-by: Ivan Vecera +Acked-by: Francois Romieu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/r8169.c | 93 ++++++++++++++++++++++++++++++++-------------------- + 1 file changed, 58 insertions(+), 35 deletions(-) + +--- a/drivers/net/r8169.c ++++ b/drivers/net/r8169.c +@@ -375,6 +375,22 @@ enum features { + RTL_FEATURE_GMII = (1 << 2), + }; + ++struct rtl8169_counters { ++ __le64 tx_packets; ++ __le64 rx_packets; ++ __le64 tx_errors; ++ __le32 rx_errors; ++ __le16 rx_missed; ++ __le16 align_errors; ++ __le32 tx_one_collision; ++ __le32 tx_multi_collision; ++ __le64 rx_unicast; ++ __le64 rx_broadcast; ++ __le32 rx_multicast; ++ __le16 tx_aborted; ++ __le16 tx_underun; ++}; ++ + struct rtl8169_private { + void __iomem *mmio_addr; /* memory map physical address */ + struct pci_dev *pci_dev; /* Index of PCI device */ +@@ -416,6 +432,7 @@ struct rtl8169_private { + unsigned features; + + struct mii_if_info mii; ++ struct rtl8169_counters counters; + }; + + MODULE_AUTHOR("Realtek and the Linux r8169 crew "); +@@ -960,22 +977,6 @@ static const char rtl8169_gstrings[][ETH + "tx_underrun", + }; + +-struct rtl8169_counters { +- __le64 tx_packets; +- __le64 rx_packets; +- __le64 tx_errors; +- __le32 rx_errors; +- __le16 rx_missed; +- __le16 align_errors; +- __le32 tx_one_collision; +- __le32 tx_multi_collision; +- __le64 rx_unicast; +- __le64 rx_broadcast; +- __le32 rx_multicast; +- __le16 tx_aborted; +- __le16 tx_underun; +-}; +- + static int rtl8169_get_sset_count(struct net_device *dev, int sset) + { + switch (sset) { +@@ -986,16 +987,21 @@ static int rtl8169_get_sset_count(struct + } + } + +-static void rtl8169_get_ethtool_stats(struct net_device *dev, +- struct ethtool_stats *stats, u64 *data) ++static void rtl8169_update_counters(struct net_device *dev) + { + struct rtl8169_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->mmio_addr; + struct rtl8169_counters *counters; + dma_addr_t paddr; + u32 cmd; ++ int wait = 1000; + +- ASSERT_RTNL(); ++ /* ++ * Some chips are unable to dump tally counters when the receiver ++ * is disabled. ++ */ ++ if ((RTL_R8(ChipCmd) & CmdRxEnb) == 0) ++ return; + + counters = pci_alloc_consistent(tp->pci_dev, sizeof(*counters), &paddr); + if (!counters) +@@ -1006,31 +1012,45 @@ static void rtl8169_get_ethtool_stats(st + RTL_W32(CounterAddrLow, cmd); + RTL_W32(CounterAddrLow, cmd | CounterDump); + +- while (RTL_R32(CounterAddrLow) & CounterDump) { +- if (msleep_interruptible(1)) ++ while (wait--) { ++ if ((RTL_R32(CounterAddrLow) & CounterDump) == 0) { ++ /* copy updated counters */ ++ memcpy(&tp->counters, counters, sizeof(*counters)); + break; ++ } ++ udelay(10); + } + + RTL_W32(CounterAddrLow, 0); + RTL_W32(CounterAddrHigh, 0); + +- data[0] = le64_to_cpu(counters->tx_packets); +- data[1] = le64_to_cpu(counters->rx_packets); +- data[2] = le64_to_cpu(counters->tx_errors); +- data[3] = le32_to_cpu(counters->rx_errors); +- data[4] = le16_to_cpu(counters->rx_missed); +- data[5] = le16_to_cpu(counters->align_errors); +- data[6] = le32_to_cpu(counters->tx_one_collision); +- data[7] = le32_to_cpu(counters->tx_multi_collision); +- data[8] = le64_to_cpu(counters->rx_unicast); +- data[9] = le64_to_cpu(counters->rx_broadcast); +- data[10] = le32_to_cpu(counters->rx_multicast); +- data[11] = le16_to_cpu(counters->tx_aborted); +- data[12] = le16_to_cpu(counters->tx_underun); +- + pci_free_consistent(tp->pci_dev, sizeof(*counters), counters, paddr); + } + ++static void rtl8169_get_ethtool_stats(struct net_device *dev, ++ struct ethtool_stats *stats, u64 *data) ++{ ++ struct rtl8169_private *tp = netdev_priv(dev); ++ ++ ASSERT_RTNL(); ++ ++ rtl8169_update_counters(dev); ++ ++ data[0] = le64_to_cpu(tp->counters.tx_packets); ++ data[1] = le64_to_cpu(tp->counters.rx_packets); ++ data[2] = le64_to_cpu(tp->counters.tx_errors); ++ data[3] = le32_to_cpu(tp->counters.rx_errors); ++ data[4] = le16_to_cpu(tp->counters.rx_missed); ++ data[5] = le16_to_cpu(tp->counters.align_errors); ++ data[6] = le32_to_cpu(tp->counters.tx_one_collision); ++ data[7] = le32_to_cpu(tp->counters.tx_multi_collision); ++ data[8] = le64_to_cpu(tp->counters.rx_unicast); ++ data[9] = le64_to_cpu(tp->counters.rx_broadcast); ++ data[10] = le32_to_cpu(tp->counters.rx_multicast); ++ data[11] = le16_to_cpu(tp->counters.tx_aborted); ++ data[12] = le16_to_cpu(tp->counters.tx_underun); ++} ++ + static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data) + { + switch(stringset) { +@@ -2979,6 +2999,9 @@ static int rtl8169_close(struct net_devi + struct rtl8169_private *tp = netdev_priv(dev); + struct pci_dev *pdev = tp->pci_dev; + ++ /* update counters before going down */ ++ rtl8169_update_counters(dev); ++ + rtl8169_down(dev); + + free_irq(dev->irq, dev); diff --git a/queue-2.6.27/r8169-reset-intrstatus-after-chip-reset.patch b/queue-2.6.27/r8169-reset-intrstatus-after-chip-reset.patch new file mode 100644 index 00000000000..ba3cab98a88 --- /dev/null +++ b/queue-2.6.27/r8169-reset-intrstatus-after-chip-reset.patch @@ -0,0 +1,57 @@ +From romieu@fr.zoreil.com Tue Apr 28 19:05:31 2009 +From: Francois Romieu +Date: Thu, 16 Apr 2009 23:35:17 +0200 +Subject: r8169: reset IntrStatus after chip reset +To: Greg KH +Message-ID: <20090416213517.GB26109@electric-eye.fr.zoreil.com> +Content-Disposition: inline + +From: Francois Romieu + +Upstream as d78ad8cbfe73ad568de38814a75e9c92ad0a907c (post 2.6.29). + +Original comment (Karsten): +On a MSI MS-6702E mainboard, when in rtl8169_init_one() for the first time +after BIOS has run, IntrStatus reads 5 after chip has been reset. +IntrStatus should equal 0 there, so patch changes IntrStatus reset to happen +after chip reset instead of before. + +Remark (Francois): +Assuming that the loglevel of the driver is increased above NETIF_MSG_INTR, +the bug reveals itself with a typical "interrupt 0025 in poll" message +at startup. In retrospect, the message should had been read as an hint of +an unexpected hardware state several months ago :o( + +Fixes (at least part of) https://bugzilla.redhat.com/show_bug.cgi?id=460747 + +Signed-off-by: Karsten Wiese +Signed-off-by: Francois Romieu +Tested-by: Josep +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/r8169.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/net/r8169.c ++++ b/drivers/net/r8169.c +@@ -1687,8 +1687,7 @@ rtl8169_init_one(struct pci_dev *pdev, c + goto err_out_free_res_4; + } + +- /* Unneeded ? Don't mess with Mrs. Murphy. */ +- rtl8169_irq_mask_and_ack(ioaddr); ++ RTL_W16(IntrMask, 0x0000); + + /* Soft reset the chip. */ + RTL_W8(ChipCmd, CmdReset); +@@ -1700,6 +1699,8 @@ rtl8169_init_one(struct pci_dev *pdev, c + msleep_interruptible(1); + } + ++ RTL_W16(IntrStatus, 0xffff); ++ + /* Identify chip attached to board */ + rtl8169_get_mac_version(tp, ioaddr); + diff --git a/queue-2.6.27/r8169-use-hardware-auto-padding.patch b/queue-2.6.27/r8169-use-hardware-auto-padding.patch new file mode 100644 index 00000000000..24898d9f6ac --- /dev/null +++ b/queue-2.6.27/r8169-use-hardware-auto-padding.patch @@ -0,0 +1,47 @@ +From romieu@fr.zoreil.com Tue Apr 28 19:05:11 2009 +From: Francois Romieu +Date: Thu, 16 Apr 2009 23:34:24 +0200 +Subject: r8169: use hardware auto-padding. +To: Greg KH +Message-ID: <20090416213424.GA26109@electric-eye.fr.zoreil.com> +Content-Disposition: inline + +From: Francois Romieu + +Upstream as 97d477a914b146e7e6722ded21afa79886ae8ccd (post 2.6.28). + +It shortens the code and fixes the current pci_unmap leak with +padded skb reported by Dave Jones. + +Signed-off-by: Francois Romieu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/r8169.c | 8 -------- + 1 file changed, 8 deletions(-) + +--- a/drivers/net/r8169.c ++++ b/drivers/net/r8169.c +@@ -2549,13 +2549,6 @@ static int rtl8169_start_xmit(struct sk_ + opts1 |= FirstFrag; + } else { + len = skb->len; +- +- if (unlikely(len < ETH_ZLEN)) { +- if (skb_padto(skb, ETH_ZLEN)) +- goto err_update_stats; +- len = ETH_ZLEN; +- } +- + opts1 |= FirstFrag | LastFrag; + tp->tx_skb[entry].skb = skb; + } +@@ -2593,7 +2586,6 @@ out: + err_stop: + netif_stop_queue(dev); + ret = NETDEV_TX_BUSY; +-err_update_stats: + dev->stats.tx_dropped++; + goto out; + } diff --git a/queue-2.6.27/series b/queue-2.6.27/series index 3673e3de5e9..0e507a83246 100644 --- a/queue-2.6.27/series +++ b/queue-2.6.27/series @@ -40,3 +40,8 @@ net-fix-sctp-breakage.patch 0096-hugetlbfs-return-negative-error-code-for-bad-mount.patch kprobes-fix-locking-imbalance-in-kretprobes.patch block-revert-part-of-18ce3751ccd488c78d3827e9f6bf54e6322676fb.patch +r8169-don-t-update-statistics-counters-when-interface-is-down.patch +r8169-use-hardware-auto-padding.patch +r8169-reset-intrstatus-after-chip-reset.patch +mm-check-for-no-mmaps-in-exit_mmap.patch +powerpc-sanitize-stack-pointer-in-signal-handling-code.patch