From: Greg Kroah-Hartman Date: Thu, 19 Apr 2012 16:07:27 +0000 (-0700) Subject: 3.3-stable patches X-Git-Tag: v3.2.16~26 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ec412066d5d060d8352e592e06af35260087787a;p=thirdparty%2Fkernel%2Fstable-queue.git 3.3-stable patches added patches: fcaps-clear-the-same-personality-flags-as-suid-when-fcaps-are-used.patch fix-tlb-flushing-for-page-table-pages.patch memcg-fix-bad-page-state-after-replace_page_cache.patch serial-pl011-clear-pending-interrupts.patch serial-pl011-move-interrupt-clearing.patch --- diff --git a/queue-3.3/fcaps-clear-the-same-personality-flags-as-suid-when-fcaps-are-used.patch b/queue-3.3/fcaps-clear-the-same-personality-flags-as-suid-when-fcaps-are-used.patch new file mode 100644 index 00000000000..6f0c628b7d1 --- /dev/null +++ b/queue-3.3/fcaps-clear-the-same-personality-flags-as-suid-when-fcaps-are-used.patch @@ -0,0 +1,38 @@ +From d52fc5dde171f030170a6cb78034d166b13c9445 Mon Sep 17 00:00:00 2001 +From: Eric Paris +Date: Tue, 17 Apr 2012 16:26:54 -0400 +Subject: fcaps: clear the same personality flags as suid when fcaps are used + +From: Eric Paris + +commit d52fc5dde171f030170a6cb78034d166b13c9445 upstream. + +If a process increases permissions using fcaps all of the dangerous +personality flags which are cleared for suid apps should also be cleared. +Thus programs given priviledge with fcaps will continue to have address space +randomization enabled even if the parent tried to disable it to make it +easier to attack. + +Signed-off-by: Eric Paris +Reviewed-by: Serge Hallyn +Signed-off-by: James Morris +Signed-off-by: Greg Kroah-Hartman + +--- + security/commoncap.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/security/commoncap.c ++++ b/security/commoncap.c +@@ -504,6 +504,11 @@ int cap_bprm_set_creds(struct linux_binp + } + skip: + ++ /* if we have fs caps, clear dangerous personality flags */ ++ if (!cap_issubset(new->cap_permitted, old->cap_permitted)) ++ bprm->per_clear |= PER_CLEAR_ON_SETID; ++ ++ + /* Don't let someone trace a set[ug]id/setpcap binary with the revised + * credentials unless they have the appropriate permit + */ diff --git a/queue-3.3/fix-tlb-flushing-for-page-table-pages.patch b/queue-3.3/fix-tlb-flushing-for-page-table-pages.patch new file mode 100644 index 00000000000..8c4583a5ad8 --- /dev/null +++ b/queue-3.3/fix-tlb-flushing-for-page-table-pages.patch @@ -0,0 +1,232 @@ +From cd94154cc6a28dd9dc271042c1a59c08d26da886 Mon Sep 17 00:00:00 2001 +From: Martin Schwidefsky +Date: Wed, 11 Apr 2012 14:28:07 +0200 +Subject: [S390] fix tlb flushing for page table pages + +From: Martin Schwidefsky + +commit cd94154cc6a28dd9dc271042c1a59c08d26da886 upstream. + +Git commit 36409f6353fc2d7b6516e631415f938eadd92ffa "use generic RCU +page-table freeing code" introduced a tlb flushing bug. Partially revert +the above git commit and go back to s390 specific page table flush code. + +For s390 the TLB can contain three types of entries, "normal" TLB +page-table entries, TLB combined region-and-segment-table (CRST) entries +and real-space entries. Linux does not use real-space entries which +leaves normal TLB entries and CRST entries. The CRST entries are +intermediate steps in the page-table translation called translation paths. +For example a 4K page access in a three-level page table setup will +create two CRST TLB entries and one page-table TLB entry. The advantage +of that approach is that a page access next to the previous one can reuse +the CRST entries and needs just a single read from memory to create the +page-table TLB entry. The disadvantage is that the TLB flushing rules are +more complicated, before any page-table may be freed the TLB needs to be +flushed. + +In short: the generic RCU page-table freeing code is incorrect for the +CRST entries, in particular the check for mm_users < 2 is troublesome. + +This is applicable to 3.0+ kernels. + +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman + +--- + arch/s390/Kconfig | 1 + arch/s390/include/asm/pgalloc.h | 3 - + arch/s390/include/asm/tlb.h | 22 ------------- + arch/s390/mm/pgtable.c | 63 ++++++++++++++++++++++++++++++++++++++-- + 4 files changed, 61 insertions(+), 28 deletions(-) + +--- a/arch/s390/Kconfig ++++ b/arch/s390/Kconfig +@@ -89,7 +89,6 @@ config S390 + select HAVE_KERNEL_XZ + select HAVE_ARCH_MUTEX_CPU_RELAX + select HAVE_ARCH_JUMP_LABEL if !MARCH_G5 +- select HAVE_RCU_TABLE_FREE if SMP + select ARCH_SAVE_PAGE_KEYS if HIBERNATION + select HAVE_MEMBLOCK + select HAVE_MEMBLOCK_NODE_MAP +--- a/arch/s390/include/asm/pgalloc.h ++++ b/arch/s390/include/asm/pgalloc.h +@@ -22,10 +22,7 @@ void crst_table_free(struct mm_struct *, + + unsigned long *page_table_alloc(struct mm_struct *, unsigned long); + void page_table_free(struct mm_struct *, unsigned long *); +-#ifdef CONFIG_HAVE_RCU_TABLE_FREE + void page_table_free_rcu(struct mmu_gather *, unsigned long *); +-void __tlb_remove_table(void *_table); +-#endif + + static inline void clear_table(unsigned long *s, unsigned long val, size_t n) + { +--- a/arch/s390/include/asm/tlb.h ++++ b/arch/s390/include/asm/tlb.h +@@ -30,14 +30,10 @@ + + struct mmu_gather { + struct mm_struct *mm; +-#ifdef CONFIG_HAVE_RCU_TABLE_FREE + struct mmu_table_batch *batch; +-#endif + unsigned int fullmm; +- unsigned int need_flush; + }; + +-#ifdef CONFIG_HAVE_RCU_TABLE_FREE + struct mmu_table_batch { + struct rcu_head rcu; + unsigned int nr; +@@ -49,7 +45,6 @@ struct mmu_table_batch { + + extern void tlb_table_flush(struct mmu_gather *tlb); + extern void tlb_remove_table(struct mmu_gather *tlb, void *table); +-#endif + + static inline void tlb_gather_mmu(struct mmu_gather *tlb, + struct mm_struct *mm, +@@ -57,29 +52,20 @@ static inline void tlb_gather_mmu(struct + { + tlb->mm = mm; + tlb->fullmm = full_mm_flush; +- tlb->need_flush = 0; +-#ifdef CONFIG_HAVE_RCU_TABLE_FREE + tlb->batch = NULL; +-#endif + if (tlb->fullmm) + __tlb_flush_mm(mm); + } + + static inline void tlb_flush_mmu(struct mmu_gather *tlb) + { +- if (!tlb->need_flush) +- return; +- tlb->need_flush = 0; +- __tlb_flush_mm(tlb->mm); +-#ifdef CONFIG_HAVE_RCU_TABLE_FREE + tlb_table_flush(tlb); +-#endif + } + + static inline void tlb_finish_mmu(struct mmu_gather *tlb, + unsigned long start, unsigned long end) + { +- tlb_flush_mmu(tlb); ++ tlb_table_flush(tlb); + } + + /* +@@ -105,10 +91,8 @@ static inline void tlb_remove_page(struc + static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, + unsigned long address) + { +-#ifdef CONFIG_HAVE_RCU_TABLE_FREE + if (!tlb->fullmm) + return page_table_free_rcu(tlb, (unsigned long *) pte); +-#endif + page_table_free(tlb->mm, (unsigned long *) pte); + } + +@@ -125,10 +109,8 @@ static inline void pmd_free_tlb(struct m + #ifdef __s390x__ + if (tlb->mm->context.asce_limit <= (1UL << 31)) + return; +-#ifdef CONFIG_HAVE_RCU_TABLE_FREE + if (!tlb->fullmm) + return tlb_remove_table(tlb, pmd); +-#endif + crst_table_free(tlb->mm, (unsigned long *) pmd); + #endif + } +@@ -146,10 +128,8 @@ static inline void pud_free_tlb(struct m + #ifdef __s390x__ + if (tlb->mm->context.asce_limit <= (1UL << 42)) + return; +-#ifdef CONFIG_HAVE_RCU_TABLE_FREE + if (!tlb->fullmm) + return tlb_remove_table(tlb, pud); +-#endif + crst_table_free(tlb->mm, (unsigned long *) pud); + #endif + } +--- a/arch/s390/mm/pgtable.c ++++ b/arch/s390/mm/pgtable.c +@@ -679,8 +679,6 @@ void page_table_free(struct mm_struct *m + } + } + +-#ifdef CONFIG_HAVE_RCU_TABLE_FREE +- + static void __page_table_free_rcu(void *table, unsigned bit) + { + struct page *page; +@@ -734,7 +732,66 @@ void __tlb_remove_table(void *_table) + free_pages((unsigned long) table, ALLOC_ORDER); + } + +-#endif ++static void tlb_remove_table_smp_sync(void *arg) ++{ ++ /* Simply deliver the interrupt */ ++} ++ ++static void tlb_remove_table_one(void *table) ++{ ++ /* ++ * This isn't an RCU grace period and hence the page-tables cannot be ++ * assumed to be actually RCU-freed. ++ * ++ * It is however sufficient for software page-table walkers that rely ++ * on IRQ disabling. See the comment near struct mmu_table_batch. ++ */ ++ smp_call_function(tlb_remove_table_smp_sync, NULL, 1); ++ __tlb_remove_table(table); ++} ++ ++static void tlb_remove_table_rcu(struct rcu_head *head) ++{ ++ struct mmu_table_batch *batch; ++ int i; ++ ++ batch = container_of(head, struct mmu_table_batch, rcu); ++ ++ for (i = 0; i < batch->nr; i++) ++ __tlb_remove_table(batch->tables[i]); ++ ++ free_page((unsigned long)batch); ++} ++ ++void tlb_table_flush(struct mmu_gather *tlb) ++{ ++ struct mmu_table_batch **batch = &tlb->batch; ++ ++ if (*batch) { ++ __tlb_flush_mm(tlb->mm); ++ call_rcu_sched(&(*batch)->rcu, tlb_remove_table_rcu); ++ *batch = NULL; ++ } ++} ++ ++void tlb_remove_table(struct mmu_gather *tlb, void *table) ++{ ++ struct mmu_table_batch **batch = &tlb->batch; ++ ++ if (*batch == NULL) { ++ *batch = (struct mmu_table_batch *) ++ __get_free_page(GFP_NOWAIT | __GFP_NOWARN); ++ if (*batch == NULL) { ++ __tlb_flush_mm(tlb->mm); ++ tlb_remove_table_one(table); ++ return; ++ } ++ (*batch)->nr = 0; ++ } ++ (*batch)->tables[(*batch)->nr++] = table; ++ if ((*batch)->nr == MAX_TABLE_BATCH) ++ tlb_table_flush(tlb); ++} + + /* + * switch on pgstes for its userspace process (for kvm) diff --git a/queue-3.3/memcg-fix-bad-page-state-after-replace_page_cache.patch b/queue-3.3/memcg-fix-bad-page-state-after-replace_page_cache.patch new file mode 100644 index 00000000000..481a122b444 --- /dev/null +++ b/queue-3.3/memcg-fix-bad-page-state-after-replace_page_cache.patch @@ -0,0 +1,36 @@ +From 9b7f43afd417a6feb80841d30ced4051c362eb5d Mon Sep 17 00:00:00 2001 +From: Hugh Dickins +Date: Wed, 18 Apr 2012 23:34:46 -0700 +Subject: memcg: fix Bad page state after replace_page_cache + +From: Hugh Dickins + +commit 9b7f43afd417a6feb80841d30ced4051c362eb5d upstream. + +My 9ce70c0240d0 "memcg: fix deadlock by inverting lrucare nesting" put a +nasty little bug into v3.3's version of mem_cgroup_replace_page_cache(), +sometimes used for FUSE. Replacing __mem_cgroup_commit_charge_lrucare() +by __mem_cgroup_commit_charge(), I used the "pc" pointer set up earlier: +but it's for oldpage, and needs now to be for newpage. Once oldpage was +freed, its PageCgroupUsed bit (cleared above but set again here) caused +"Bad page state" messages - and perhaps worse, being missed from newpage. +(I didn't find this by using FUSE, but in reusing the function for tmpfs.) + +Signed-off-by: Hugh Dickins +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/memcontrol.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -3350,6 +3350,7 @@ void mem_cgroup_replace_page_cache(struc + * the newpage may be on LRU(or pagevec for LRU) already. We lock + * LRU while we overwrite pc->mem_cgroup. + */ ++ pc = lookup_page_cgroup(newpage); + __mem_cgroup_commit_charge(memcg, newpage, 1, pc, type, true); + } + diff --git a/queue-3.3/serial-pl011-clear-pending-interrupts.patch b/queue-3.3/serial-pl011-clear-pending-interrupts.patch new file mode 100644 index 00000000000..477d7fb5427 --- /dev/null +++ b/queue-3.3/serial-pl011-clear-pending-interrupts.patch @@ -0,0 +1,80 @@ +From 9b96fbacda34079dea0638ee1e92c56286f6114a Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Tue, 13 Mar 2012 13:27:23 +0100 +Subject: serial: PL011: clear pending interrupts + +From: Linus Walleij + +commit 9b96fbacda34079dea0638ee1e92c56286f6114a upstream. + +Chanho Min reported that when the boot loader transfers +control to the kernel, there may be pending interrupts +causing the UART to lock up in an eternal loop trying to +pick tokens from the FIFO (since the RX interrupt flag +indicates there are tokens) while in practice there are +no tokens - in fact there is only a pending IRQ flag. + +This patch address the issue with a combination of two +patches suggested by Russell King that clears and mask +all interrupts at probe() and clears any pending error +and RX interrupts at port startup time. + +We suspect the spurious interrupts are a side-effect of +switching the UART from FIFO to non-FIFO mode. + +Cc: Shreshtha Kumar Sahu +Reported-by: Chanho Min +Suggested-by: Russell King +Signed-off-by: Linus Walleij +Reviewed-by: Jong-Sung Kim +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/serial/amba-pl011.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +--- a/drivers/tty/serial/amba-pl011.c ++++ b/drivers/tty/serial/amba-pl011.c +@@ -1381,6 +1381,10 @@ static int pl011_startup(struct uart_por + + uap->port.uartclk = clk_get_rate(uap->clk); + ++ /* Clear pending error and receive interrupts */ ++ writew(UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS | ++ UART011_RTIS | UART011_RXIS, uap->port.membase + UART011_ICR); ++ + /* + * Allocate the IRQ + */ +@@ -1417,10 +1421,6 @@ static int pl011_startup(struct uart_por + cr |= UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE; + writew(cr, uap->port.membase + UART011_CR); + +- /* Clear pending error interrupts */ +- writew(UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS, +- uap->port.membase + UART011_ICR); +- + /* + * initialise the old status of the modem signals + */ +@@ -1435,6 +1435,9 @@ static int pl011_startup(struct uart_por + * as well. + */ + spin_lock_irq(&uap->port.lock); ++ /* Clear out any spuriously appearing RX interrupts */ ++ writew(UART011_RTIS | UART011_RXIS, ++ uap->port.membase + UART011_ICR); + uap->im = UART011_RTIM; + if (!pl011_dma_rx_running(uap)) + uap->im |= UART011_RXIM; +@@ -1927,6 +1930,10 @@ static int pl011_probe(struct amba_devic + goto unmap; + } + ++ /* Ensure interrupts from this UART are masked and cleared */ ++ writew(0, uap->port.membase + UART011_IMSC); ++ writew(0xffff, uap->port.membase + UART011_ICR); ++ + uap->vendor = vendor; + uap->lcrh_rx = vendor->lcrh_rx; + uap->lcrh_tx = vendor->lcrh_tx; diff --git a/queue-3.3/serial-pl011-move-interrupt-clearing.patch b/queue-3.3/serial-pl011-move-interrupt-clearing.patch new file mode 100644 index 00000000000..a91a6f3c22e --- /dev/null +++ b/queue-3.3/serial-pl011-move-interrupt-clearing.patch @@ -0,0 +1,53 @@ +From c3d8b76f61586714cdc5f219ba45592a54caaa55 Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Wed, 21 Mar 2012 20:15:18 +0100 +Subject: serial: PL011: move interrupt clearing + +From: Linus Walleij + +commit c3d8b76f61586714cdc5f219ba45592a54caaa55 upstream. + +Commit 360f748b204275229f8398cb2f9f53955db1503b +"serial: PL011: clear pending interrupts" +attempts to clear interrupts by writing to a +yet-unassigned memory address. This fixes the issue. + +The breaking patch is marked for stable so should be +carried along with the other patch. + +Cc: Shreshtha Kumar Sahu +Cc: Russell King +Cc: Nicolas Pitre +Reported-by: Viresh Kumar +Signed-off-by: Linus Walleij +Tested-by: Grant Likely +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/serial/amba-pl011.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/tty/serial/amba-pl011.c ++++ b/drivers/tty/serial/amba-pl011.c +@@ -1930,10 +1930,6 @@ static int pl011_probe(struct amba_devic + goto unmap; + } + +- /* Ensure interrupts from this UART are masked and cleared */ +- writew(0, uap->port.membase + UART011_IMSC); +- writew(0xffff, uap->port.membase + UART011_ICR); +- + uap->vendor = vendor; + uap->lcrh_rx = vendor->lcrh_rx; + uap->lcrh_tx = vendor->lcrh_tx; +@@ -1951,6 +1947,10 @@ static int pl011_probe(struct amba_devic + uap->port.line = i; + pl011_dma_probe(uap); + ++ /* Ensure interrupts from this UART are masked and cleared */ ++ writew(0, uap->port.membase + UART011_IMSC); ++ writew(0xffff, uap->port.membase + UART011_ICR); ++ + snprintf(uap->type, sizeof(uap->type), "PL011 rev%u", amba_rev(dev)); + + amba_ports[i] = uap; diff --git a/queue-3.3/series b/queue-3.3/series index 45bb5ad9fad..f57f1d2551b 100644 --- a/queue-3.3/series +++ b/queue-3.3/series @@ -52,3 +52,8 @@ xhci-restore-event-ring-dequeue-pointer-on-resume.patch usb-fix-bug-of-device-descriptor-got-from-superspeed-device.patch xhci-add-xhci_reset_on_resume-quirk-for-via-xhci-host.patch xhci-correct-the-define-xhci_legacy_disable_smi.patch +fix-tlb-flushing-for-page-table-pages.patch +memcg-fix-bad-page-state-after-replace_page_cache.patch +serial-pl011-clear-pending-interrupts.patch +serial-pl011-move-interrupt-clearing.patch +fcaps-clear-the-same-personality-flags-as-suid-when-fcaps-are-used.patch