From 9fbcbd7e1fa9acde67f3516f7aceef2c0d968a7b Mon Sep 17 00:00:00 2001 From: Hillf Danton Date: Thu, 4 Aug 2011 22:38:31 +0800 Subject: MIPS: VPE: Select correct tc If we could find tc on the tc list for @index, the found tc should be returned. Signed-off-by: Hillf Danton To: LKML Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2692/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/vpe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 2cd50ad0d5c..3efcb065f78 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c @@ -192,7 +192,7 @@ static struct tc *get_tc(int index) } spin_unlock(&vpecontrol.tc_list_lock); - return NULL; + return res; } /* allocate a vpe and associate it with this minor (or index) */ -- cgit v1.2.3 From fe0b030cf016ee9a4b0ae4adb0095c46d0e461cc Mon Sep 17 00:00:00 2001 From: Hillf Danton Date: Thu, 4 Aug 2011 22:46:41 +0800 Subject: MIPS: i8259: Correct comment for i8259 The comment for the slave PIC is changed from 8259A-1 to 8259A-2. Signed-off-by: Hillf Danton To: LKML Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2693/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/i8259.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c index 5c74eb797f0..9b22db5dcef 100644 --- a/arch/mips/kernel/i8259.c +++ b/arch/mips/kernel/i8259.c @@ -229,7 +229,7 @@ static void i8259A_shutdown(void) */ if (i8259A_auto_eoi >= 0) { outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ - outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */ + outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */ } } -- cgit v1.2.3 From 16650107579aed81e0b0534a60400f9ba911fe9b Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Sat, 18 Jun 2011 11:28:48 -0700 Subject: MIPS: Trivial style cleanups in mmap.c Fix checkpatch warnings. Rename arch_get_unmapped_area_foo() to arch_get_unmapped_area_common(). Make indentations and spacing more consistent. Add for likely/unlikely. Signed-off-by: Kevin Cernekee Cc: Jian Peng Cc: David Daney Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2506/ Signed-off-by: Ralf Baechle --- arch/mips/mm/mmap.c | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c index 9ff5d0fac55..302d779d5b0 100644 --- a/arch/mips/mm/mmap.c +++ b/arch/mips/mm/mmap.c @@ -6,6 +6,7 @@ * Copyright (C) 2011 Wind River Systems, * written by Ralf Baechle */ +#include #include #include #include @@ -15,12 +16,11 @@ #include unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */ - EXPORT_SYMBOL(shm_align_mask); /* gap between mmap and stack */ #define MIN_GAP (128*1024*1024UL) -#define MAX_GAP ((TASK_SIZE)/6*5) +#define MAX_GAP ((TASK_SIZE)/6*5) static int mmap_is_legacy(void) { @@ -57,13 +57,13 @@ static inline unsigned long COLOUR_ALIGN_DOWN(unsigned long addr, return base - off; } -#define COLOUR_ALIGN(addr,pgoff) \ +#define COLOUR_ALIGN(addr, pgoff) \ ((((addr) + shm_align_mask) & ~shm_align_mask) + \ (((pgoff) << PAGE_SHIFT) & shm_align_mask)) enum mmap_allocation_direction {UP, DOWN}; -static unsigned long arch_get_unmapped_area_foo(struct file *filp, +static unsigned long arch_get_unmapped_area_common(struct file *filp, unsigned long addr0, unsigned long len, unsigned long pgoff, unsigned long flags, enum mmap_allocation_direction dir) { @@ -103,16 +103,16 @@ static unsigned long arch_get_unmapped_area_foo(struct file *filp, vma = find_vma(mm, addr); if (TASK_SIZE - len >= addr && - (!vma || addr + len <= vma->vm_start)) + (!vma || addr + len <= vma->vm_start)) return addr; } if (dir == UP) { addr = mm->mmap_base; - if (do_color_align) - addr = COLOUR_ALIGN(addr, pgoff); - else - addr = PAGE_ALIGN(addr); + if (do_color_align) + addr = COLOUR_ALIGN(addr, pgoff); + else + addr = PAGE_ALIGN(addr); for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) { /* At this point: (!vma || addr < vma->vm_end). */ @@ -131,28 +131,30 @@ static unsigned long arch_get_unmapped_area_foo(struct file *filp, mm->free_area_cache = mm->mmap_base; } - /* either no address requested or can't fit in requested address hole */ + /* + * either no address requested, or the mapping can't fit into + * the requested address hole + */ addr = mm->free_area_cache; - if (do_color_align) { - unsigned long base = - COLOUR_ALIGN_DOWN(addr - len, pgoff); - + if (do_color_align) { + unsigned long base = + COLOUR_ALIGN_DOWN(addr - len, pgoff); addr = base + len; - } + } /* make sure it can fit in the remaining address space */ if (likely(addr > len)) { vma = find_vma(mm, addr - len); if (!vma || addr <= vma->vm_start) { - /* remember the address as a hint for next time */ - return mm->free_area_cache = addr-len; + /* cache the address as a hint for next time */ + return mm->free_area_cache = addr - len; } } if (unlikely(mm->mmap_base < len)) goto bottomup; - addr = mm->mmap_base-len; + addr = mm->mmap_base - len; if (do_color_align) addr = COLOUR_ALIGN_DOWN(addr, pgoff); @@ -163,8 +165,8 @@ static unsigned long arch_get_unmapped_area_foo(struct file *filp, * return with success: */ vma = find_vma(mm, addr); - if (likely(!vma || addr+len <= vma->vm_start)) { - /* remember the address as a hint for next time */ + if (likely(!vma || addr + len <= vma->vm_start)) { + /* cache the address as a hint for next time */ return mm->free_area_cache = addr; } @@ -173,7 +175,7 @@ static unsigned long arch_get_unmapped_area_foo(struct file *filp, mm->cached_hole_size = vma->vm_start - addr; /* try just below the current vma->vm_start */ - addr = vma->vm_start-len; + addr = vma->vm_start - len; if (do_color_align) addr = COLOUR_ALIGN_DOWN(addr, pgoff); } while (likely(len < vma->vm_start)); @@ -201,7 +203,7 @@ bottomup: unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr0, unsigned long len, unsigned long pgoff, unsigned long flags) { - return arch_get_unmapped_area_foo(filp, + return arch_get_unmapped_area_common(filp, addr0, len, pgoff, flags, UP); } @@ -213,7 +215,7 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr0, unsigned long len, unsigned long pgoff, unsigned long flags) { - return arch_get_unmapped_area_foo(filp, + return arch_get_unmapped_area_common(filp, addr0, len, pgoff, flags, DOWN); } -- cgit v1.2.3 From d4001e086babc77f26b599893d803a2b6e46d602 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 23 Jun 2011 22:07:13 +0200 Subject: MIPS: Remove unneeded version.h includes from arch/mips/ It was pointed out by 'make versioncheck' that some includes of linux/version.h are not needed in arch/mips/. This patch removes them. Signed-off-by: Jesper Juhl To: LKML Cc: trivial@kernel.org Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2540/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-powertv/dma-coherence.h | 1 - arch/mips/lantiq/xway/ebu.c | 1 - arch/mips/lantiq/xway/pmu.c | 1 - 3 files changed, 3 deletions(-) diff --git a/arch/mips/include/asm/mach-powertv/dma-coherence.h b/arch/mips/include/asm/mach-powertv/dma-coherence.h index 62c09408594..35371641575 100644 --- a/arch/mips/include/asm/mach-powertv/dma-coherence.h +++ b/arch/mips/include/asm/mach-powertv/dma-coherence.h @@ -13,7 +13,6 @@ #define __ASM_MACH_POWERTV_DMA_COHERENCE_H #include -#include #include #include diff --git a/arch/mips/lantiq/xway/ebu.c b/arch/mips/lantiq/xway/ebu.c index 66eb52fa50a..033b3184c7a 100644 --- a/arch/mips/lantiq/xway/ebu.c +++ b/arch/mips/lantiq/xway/ebu.c @@ -10,7 +10,6 @@ #include #include -#include #include #include diff --git a/arch/mips/lantiq/xway/pmu.c b/arch/mips/lantiq/xway/pmu.c index 9d69f01e352..39f0d2641cb 100644 --- a/arch/mips/lantiq/xway/pmu.c +++ b/arch/mips/lantiq/xway/pmu.c @@ -8,7 +8,6 @@ #include #include -#include #include #include -- cgit v1.2.3 From 20ef5d3a23d5aacb85d0a2808d949e3daf83cd20 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Tue, 26 Jul 2011 18:19:01 +0900 Subject: MIPS: RC32434: Fix PCI build error arch/mips/pci/pci-rc32434.c: In function 'rc32434_pci_init': arch/mips/pci/pci-rc32434.c:217:16: error: 'rcrc32434_res_pci_io1' undeclared (first use in this function) arch/mips/pci/pci-rc32434.c:217:16: note: each undeclared identifier is reported only once for each function it appears in make[1]: *** [arch/mips/pci/pci-rc32434.o] Error 1 This problem is included in the following commit. commit 28f65c11f2ffb3957259dece647a24f8ad2e241b Author: Joe Perches Date: Thu Jun 9 09:13:32 2011 -0700 treewide: Convert uses of struct resource to resource_size(ptr) Signed-off-by: Yoichi Yuasa Cc: linux-mips Cc: Joe Perches Patchwork: https://patchwork.linux-mips.org/patch/2654/ Signed-off-by: Ralf Baechle --- arch/mips/pci/pci-rc32434.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/pci/pci-rc32434.c b/arch/mips/pci/pci-rc32434.c index 764362ce5e4..5f3a69cebad 100644 --- a/arch/mips/pci/pci-rc32434.c +++ b/arch/mips/pci/pci-rc32434.c @@ -215,7 +215,7 @@ static int __init rc32434_pci_init(void) rc32434_pcibridge_init(); io_map_base = ioremap(rc32434_res_pci_io1.start, - resource_size(&rcrc32434_res_pci_io1)); + resource_size(&rc32434_res_pci_io1)); if (!io_map_base) return -ENOMEM; -- cgit v1.2.3 From 49de830ad7b94d05f6dbfbae97a03f80169a7462 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 23 Jul 2011 12:41:23 +0000 Subject: MIPS: Ftrace: Fix the CONFIG_DYNAMIC_FTRACE=n compile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit arch/mips/kernel/ftrace.c: In function ‘ftrace_get_parent_ra_addr’: arch/mips/kernel/ftrace.c:212: error: implicit declaration of function ‘in_kernel_space’ arch/mips/kernel/ftrace.c: In function ‘prepare_ftrace_return’: arch/mips/kernel/ftrace.c:314: error: ‘MCOUNT_OFFSET_INSNS’ undeclared (first use in this function) arch/mips/kernel/ftrace.c:314: error: (Each undeclared identifier is reported only once arch/mips/kernel/ftrace.c:314: error: for each function it appears in.) Signed-off-by: Thomas Gleixner To: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2634/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/ftrace.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c index feb8021a305..6a2d758dd8e 100644 --- a/arch/mips/kernel/ftrace.c +++ b/arch/mips/kernel/ftrace.c @@ -19,6 +19,26 @@ #include +#if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT) +#define MCOUNT_OFFSET_INSNS 5 +#else +#define MCOUNT_OFFSET_INSNS 4 +#endif + +/* + * Check if the address is in kernel space + * + * Clone core_kernel_text() from kernel/extable.c, but doesn't call + * init_kernel_text() for Ftrace doesn't trace functions in init sections. + */ +static inline int in_kernel_space(unsigned long ip) +{ + if (ip >= (unsigned long)_stext && + ip <= (unsigned long)_etext) + return 1; + return 0; +} + #ifdef CONFIG_DYNAMIC_FTRACE #define JAL 0x0c000000 /* jump & link: ip --> ra, jump to target */ @@ -54,20 +74,6 @@ static inline void ftrace_dyn_arch_init_insns(void) #endif } -/* - * Check if the address is in kernel space - * - * Clone core_kernel_text() from kernel/extable.c, but doesn't call - * init_kernel_text() for Ftrace doesn't trace functions in init sections. - */ -static inline int in_kernel_space(unsigned long ip) -{ - if (ip >= (unsigned long)_stext && - ip <= (unsigned long)_etext) - return 1; - return 0; -} - static int ftrace_modify_code(unsigned long ip, unsigned int new_code) { int faulted; @@ -112,11 +118,6 @@ static int ftrace_modify_code(unsigned long ip, unsigned int new_code) * 1: offset = 4 instructions */ -#if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT) -#define MCOUNT_OFFSET_INSNS 5 -#else -#define MCOUNT_OFFSET_INSNS 4 -#endif #define INSN_B_1F (0x10000000 | MCOUNT_OFFSET_INSNS) int ftrace_make_nop(struct module *mod, -- cgit v1.2.3 From 4d85f6afa43d366868fdaa19595722309e4843f6 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Sat, 23 Jul 2011 12:41:24 +0000 Subject: MIPS: Make the die_lock be raw On preempt-rt this lock needs to be raw, so it does not get converted to a sleeping spinlock. Trying to sleep in a panic is not really desireable. Signed-off-by: Wu Zhangjin Signed-off-by: Thomas Gleixner Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2636/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/traps.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index b7517e3abc8..01eff7e609e 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -364,7 +364,7 @@ static int regs_to_trapnr(struct pt_regs *regs) return (regs->cp0_cause >> 2) & 0x1f; } -static DEFINE_SPINLOCK(die_lock); +static DEFINE_RAW_SPINLOCK(die_lock); void __noreturn die(const char *str, struct pt_regs *regs) { @@ -378,7 +378,7 @@ void __noreturn die(const char *str, struct pt_regs *regs) sig = 0; console_verbose(); - spin_lock_irq(&die_lock); + raw_spin_lock_irq(&die_lock); bust_spinlocks(1); #ifdef CONFIG_MIPS_MT_SMTC mips_mt_regdump(dvpret); @@ -387,7 +387,7 @@ void __noreturn die(const char *str, struct pt_regs *regs) printk("%s[#%d]:\n", str, ++die_counter); show_registers(regs); add_taint(TAINT_DIE); - spin_unlock_irq(&die_lock); + raw_spin_unlock_irq(&die_lock); if (in_interrupt()) panic("Fatal exception in interrupt"); -- cgit v1.2.3 From 5a4a4ad851dd8db2d888fb86c8bd946b2ae79f60 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Sat, 23 Jul 2011 12:41:24 +0000 Subject: MIPS: Mark cascade and low level interrupts IRQF_NO_THREAD Mark interrupts with no_action handler, cascade interrupts, low level interrupts (bus error, halt ..) with IRQF_NO_THREAD to exclude them from forced threading. Signed-off-by: Wu Zhangjin Signed-off-by: Thomas Gleixner Cc: linux-mips@linux-mips.org Cc: Wu Zhangjin Signed-off-by: Ralf Baechle --- arch/mips/ar7/irq.c | 3 ++- arch/mips/bcm63xx/irq.c | 1 + arch/mips/cobalt/irq.c | 1 + arch/mips/dec/setup.c | 4 ++++ arch/mips/emma/markeins/irq.c | 2 +- arch/mips/lasat/interrupt.c | 1 + arch/mips/mti-malta/malta-int.c | 6 ++++-- arch/mips/pmc-sierra/msp71xx/msp_irq.c | 2 ++ arch/mips/pnx8550/common/int.c | 2 +- arch/mips/sgi-ip22/ip22-int.c | 10 +++++----- arch/mips/sni/rm200.c | 1 + arch/mips/vr41xx/common/irq.c | 1 + 12 files changed, 24 insertions(+), 10 deletions(-) diff --git a/arch/mips/ar7/irq.c b/arch/mips/ar7/irq.c index 03db3daadbd..88c4babfdb5 100644 --- a/arch/mips/ar7/irq.c +++ b/arch/mips/ar7/irq.c @@ -98,7 +98,8 @@ static struct irq_chip ar7_sec_irq_type = { static struct irqaction ar7_cascade_action = { .handler = no_action, - .name = "AR7 cascade interrupt" + .name = "AR7 cascade interrupt", + .flags = IRQF_NO_THREAD, }; static void __init ar7_irq_init(int base) diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c index cea6021cb8d..162e11b4ed7 100644 --- a/arch/mips/bcm63xx/irq.c +++ b/arch/mips/bcm63xx/irq.c @@ -222,6 +222,7 @@ static struct irq_chip bcm63xx_external_irq_chip = { static struct irqaction cpu_ip2_cascade_action = { .handler = no_action, .name = "cascade_ip2", + .flags = IRQF_NO_THREAD, }; void __init arch_init_irq(void) diff --git a/arch/mips/cobalt/irq.c b/arch/mips/cobalt/irq.c index cb9bf820fe5..965c777d356 100644 --- a/arch/mips/cobalt/irq.c +++ b/arch/mips/cobalt/irq.c @@ -48,6 +48,7 @@ asmlinkage void plat_irq_dispatch(void) static struct irqaction cascade = { .handler = no_action, .name = "cascade", + .flags = IRQF_NO_THREAD, }; void __init arch_init_irq(void) diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c index fa45e924be0..f7b7ba6d5c4 100644 --- a/arch/mips/dec/setup.c +++ b/arch/mips/dec/setup.c @@ -101,20 +101,24 @@ int cpu_fpu_mask = DEC_CPU_IRQ_MASK(DEC_CPU_INR_FPU); static struct irqaction ioirq = { .handler = no_action, .name = "cascade", + .flags = IRQF_NO_THREAD, }; static struct irqaction fpuirq = { .handler = no_action, .name = "fpu", + .flags = IRQF_NO_THREAD, }; static struct irqaction busirq = { .flags = IRQF_DISABLED, .name = "bus error", + .flags = IRQF_NO_THREAD, }; static struct irqaction haltirq = { .handler = dec_intr_halt, .name = "halt", + .flags = IRQF_NO_THREAD, }; diff --git a/arch/mips/emma/markeins/irq.c b/arch/mips/emma/markeins/irq.c index 3dbd7a5a6ad..7798887a128 100644 --- a/arch/mips/emma/markeins/irq.c +++ b/arch/mips/emma/markeins/irq.c @@ -169,7 +169,7 @@ void emma2rh_gpio_irq_init(void) static struct irqaction irq_cascade = { .handler = no_action, - .flags = 0, + .flags = IRQF_NO_THREAD, .name = "cascade", .dev_id = NULL, .next = NULL, diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c index de4c165515d..d608b6ef0ed 100644 --- a/arch/mips/lasat/interrupt.c +++ b/arch/mips/lasat/interrupt.c @@ -105,6 +105,7 @@ asmlinkage void plat_irq_dispatch(void) static struct irqaction cascade = { .handler = no_action, .name = "cascade", + .flags = IRQF_NO_THREAD, }; void __init arch_init_irq(void) diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index 1d36c511a7a..d53ff91b277 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -350,12 +350,14 @@ unsigned int plat_ipi_resched_int_xlate(unsigned int cpu) static struct irqaction i8259irq = { .handler = no_action, - .name = "XT-PIC cascade" + .name = "XT-PIC cascade", + .flags = IRQF_NO_THREAD, }; static struct irqaction corehi_irqaction = { .handler = no_action, - .name = "CoreHi" + .name = "CoreHi", + .flags = IRQF_NO_THREAD, }; static msc_irqmap_t __initdata msc_irqmap[] = { diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq.c b/arch/mips/pmc-sierra/msp71xx/msp_irq.c index 4531c4a514b..42a4c04e21d 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_irq.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_irq.c @@ -109,11 +109,13 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs) static struct irqaction cic_cascade_msp = { .handler = no_action, .name = "MSP CIC cascade" + .flags = IRQF_NO_THREAD, }; static struct irqaction per_cascade_msp = { .handler = no_action, .name = "MSP PER cascade" + .flags = IRQF_NO_THREAD, }; void __init arch_init_irq(void) diff --git a/arch/mips/pnx8550/common/int.c b/arch/mips/pnx8550/common/int.c index 6b93c81779c..1ebe22bdadc 100644 --- a/arch/mips/pnx8550/common/int.c +++ b/arch/mips/pnx8550/common/int.c @@ -167,7 +167,7 @@ static struct irq_chip level_irq_type = { static struct irqaction gic_action = { .handler = no_action, - .flags = IRQF_DISABLED, + .flags = IRQF_DISABLED | IRQF_NO_THREAD, .name = "GIC", }; diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c index b4d08e4d2ea..f72c336ea27 100644 --- a/arch/mips/sgi-ip22/ip22-int.c +++ b/arch/mips/sgi-ip22/ip22-int.c @@ -155,32 +155,32 @@ static void __irq_entry indy_buserror_irq(void) static struct irqaction local0_cascade = { .handler = no_action, - .flags = IRQF_DISABLED, + .flags = IRQF_DISABLED | IRQF_NO_THREAD, .name = "local0 cascade", }; static struct irqaction local1_cascade = { .handler = no_action, - .flags = IRQF_DISABLED, + .flags = IRQF_DISABLED | IRQF_NO_THREAD, .name = "local1 cascade", }; static struct irqaction buserr = { .handler = no_action, - .flags = IRQF_DISABLED, + .flags = IRQF_DISABLED | IRQF_NO_THREAD, .name = "Bus Error", }; static struct irqaction map0_cascade = { .handler = no_action, - .flags = IRQF_DISABLED, + .flags = IRQF_DISABLED | IRQF_NO_THREAD, .name = "mapable0 cascade", }; #ifdef USE_LIO3_IRQ static struct irqaction map1_cascade = { .handler = no_action, - .flags = IRQF_DISABLED, + .flags = IRQF_DISABLED | IRQF_NO_THREAD, .name = "mapable1 cascade", }; #define SGI_INTERRUPTS SGINT_END diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c index a7e5a6d917b..3ab5b5d25b0 100644 --- a/arch/mips/sni/rm200.c +++ b/arch/mips/sni/rm200.c @@ -359,6 +359,7 @@ void sni_rm200_init_8259A(void) static struct irqaction sni_rm200_irq2 = { .handler = no_action, .name = "cascade", + .flags = IRQF_NO_THREAD, }; static struct resource sni_rm200_pic1_resource = { diff --git a/arch/mips/vr41xx/common/irq.c b/arch/mips/vr41xx/common/irq.c index 70a3b85f375..fad2bef432c 100644 --- a/arch/mips/vr41xx/common/irq.c +++ b/arch/mips/vr41xx/common/irq.c @@ -34,6 +34,7 @@ static irq_cascade_t irq_cascade[NR_IRQS] __cacheline_aligned; static struct irqaction cascade_irqaction = { .handler = no_action, .name = "cascade", + .flags = IRQF_NO_THREAD, }; int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int)) -- cgit v1.2.3 From 77cbece76723dc9e77497c042827155388bdae6d Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Sat, 23 Jul 2011 12:41:24 +0000 Subject: MIPS: Loongson: Mark cascade interrupts IRQF_NO_THREAD There are two cascade interrupts in Loongson machines, one for bonito northbridge, another for the 8259A controller in the southbridge. Both want to be non threaded. Signed-off-by: Wu Zhangjin Signed-off-by: Thomas Gleixner Cc: linux-mips@linux-mips.org Cc: Wu Zhangjin Patchwork: https://patchwork.linux-mips.org/patch/2638/ Signed-off-by: Ralf Baechle --- arch/mips/loongson/fuloong-2e/irq.c | 1 + arch/mips/loongson/lemote-2f/irq.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/mips/loongson/fuloong-2e/irq.c b/arch/mips/loongson/fuloong-2e/irq.c index d61a04222b8..3cf1fef29f0 100644 --- a/arch/mips/loongson/fuloong-2e/irq.c +++ b/arch/mips/loongson/fuloong-2e/irq.c @@ -42,6 +42,7 @@ asmlinkage void mach_irq_dispatch(unsigned int pending) static struct irqaction cascade_irqaction = { .handler = no_action, .name = "cascade", + .flags = IRQF_NO_THREAD, }; void __init mach_init_irq(void) diff --git a/arch/mips/loongson/lemote-2f/irq.c b/arch/mips/loongson/lemote-2f/irq.c index 081db102bb9..14b081841b6 100644 --- a/arch/mips/loongson/lemote-2f/irq.c +++ b/arch/mips/loongson/lemote-2f/irq.c @@ -96,12 +96,13 @@ static irqreturn_t ip6_action(int cpl, void *dev_id) struct irqaction ip6_irqaction = { .handler = ip6_action, .name = "cascade", - .flags = IRQF_SHARED, + .flags = IRQF_SHARED | IRQF_NO_THREAD, }; struct irqaction cascade_irqaction = { .handler = no_action, .name = "cascade", + .flags = IRQF_NO_THREAD, }; void __init mach_init_irq(void) -- cgit v1.2.3 From 5c22cd407574988cc1580108e0df25ee64ea3d59 Mon Sep 17 00:00:00 2001 From: Liming Wang Date: Fri, 26 Aug 2011 07:00:04 +0800 Subject: MIPS: i8259: Mark cascade interrupt non-threaded Cascade interrupts cannot be threaded. Signed-off-by: Liming Wang Signed-off-by: Bruce Ashfield Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1314370804-21266-1-git-send-email-liming.wang@windriver.com Signed-off-by: Thomas Gleixner Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2770/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/i8259.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c index 9b22db5dcef..32b397b646e 100644 --- a/arch/mips/kernel/i8259.c +++ b/arch/mips/kernel/i8259.c @@ -295,6 +295,7 @@ static void init_8259A(int auto_eoi) static struct irqaction irq2 = { .handler = no_action, .name = "cascade", + .flags = IRQF_NO_THREAD, }; static struct resource pic1_io_resource = { -- cgit v1.2.3 From 0f462e3c1281fd679b4c626612bfa59eb964bafd Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 23 Jul 2011 12:41:25 +0000 Subject: MIPS: Allow forced irq threading All low level interrupts have been marked NO_THREAD, so MIPS can enjoy the wonderful world of forced threaded interrupt handlers. Signed-off-by: Thomas Gleixner To: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2639/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 177cdaf8356..d300c2bf836 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -24,6 +24,7 @@ config MIPS select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW select HAVE_ARCH_JUMP_LABEL + select IRQ_FORCED_THREADING menu "Machine selection" -- cgit v1.2.3 From 1f717929e987fc55bb6be02df994945f8edbd46c Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 27 Jul 2011 11:44:47 +0100 Subject: MIPS: Handle __put_user() sleeping. do_signal() does __put_user() which can fault, resulting in a might_sleep() warning in down_read(&mm->mmap_sem) and a "scheduling while atomic" warning when mmap_sem is contented. On Swarm this also results in: WARNING: at kernel/smp.c:459 smp_call_function_many+0x148/0x398() Modules linked in: Call Trace: [] dump_stack+0x1c/0x50 [] warn_slowpath_common+0x8c/0xc8 [] warn_slowpath_null+0x2c/0x40 [] smp_call_function_many+0x148/0x398 [] smp_call_function+0x58/0xa8 [] r4k_flush_data_cache_page+0x54/0xd8 [] handle_pte_fault+0xa9c/0xad0 [] handle_mm_fault+0x158/0x200 [] do_page_fault+0x218/0x3b0 [] ret_from_exception+0x0/0x10 [] copy_siginfo_to_user32+0x50/0x298 [] setup_rt_frame_32+0x90/0x250 [] do_notify_resume+0x154/0x358 [] work_notifysig+0xc/0x14 Fixed by enabling interrupts in do_notify_resume before delivering signals. [ralf@linux-mips.org: Reported and original fix by tglx but I wanted to minimize the amount of code being run with interrupts disabled so I moved the local_irq_disable() call right into do_notify_resume. Which is saner than doing it in entry.S.] Reported-by: Thomas Gleixner Signed-off-by: Ralf Baechle --- arch/mips/kernel/signal.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index dbbe0ce48d8..f8524003676 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -8,6 +8,7 @@ * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ #include +#include #include #include #include @@ -658,6 +659,8 @@ static void do_signal(struct pt_regs *regs) asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) { + local_irq_enable(); + /* deal with pending signal delivery */ if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) do_signal(regs); -- cgit v1.2.3 From a705dc7cf4edbf110af19ea55cb5e5d0465adcf4 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 28 Jul 2011 13:31:48 +0100 Subject: MIPS: MSP71xx: Fix build error. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CC arch/mips/pmc-sierra/msp71xx/msp_irq.o /home/ralf/src/linux/linux-mips/arch/mips/pmc-sierra/msp71xx/msp_irq.c:112:2: error: request for member ‘flags’ in something not a structure or union /home/ralf/src/linux/linux-mips/arch/mips/pmc-sierra/msp71xx/msp_irq.c:118:2: error: request for member ‘flags’ in something not a structure or union make[4]: *** [arch/mips/pmc-sierra/msp71xx/msp_irq.o] Error 1 caused by 57336bc1056798d89714b7fb1b1d197e6bda6819 [MIPS: Mark cascade and low level interrupts IRQF_NO_THREAD]. Commas to separate struct initializers generally are considered useful to enhance the compilation experience of the user. Signed-off-by: Ralf Baechle --- arch/mips/pmc-sierra/msp71xx/msp_irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq.c b/arch/mips/pmc-sierra/msp71xx/msp_irq.c index 42a4c04e21d..d3c3d81757a 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_irq.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_irq.c @@ -108,13 +108,13 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs) static struct irqaction cic_cascade_msp = { .handler = no_action, - .name = "MSP CIC cascade" + .name = "MSP CIC cascade", .flags = IRQF_NO_THREAD, }; static struct irqaction per_cascade_msp = { .handler = no_action, - .name = "MSP PER cascade" + .name = "MSP PER cascade", .flags = IRQF_NO_THREAD, }; -- cgit v1.2.3 From c78c48827336b8aec2a5afcf249f0d0a7fe16859 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Tue, 2 Aug 2011 15:50:56 +0200 Subject: MIPS: Alchemy: Fix typo in MAC0 registration Harmless typo which prints an error message although MAC0 was registered successfully. Signed-off-by: Manuel Lauss To: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2672/ Signed-off-by: Ralf Baechle --- arch/mips/alchemy/common/platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c index 3b2c18b1434..f72c48d4804 100644 --- a/arch/mips/alchemy/common/platform.c +++ b/arch/mips/alchemy/common/platform.c @@ -492,7 +492,7 @@ static void __init alchemy_setup_macs(int ctype) memcpy(au1xxx_eth0_platform_data.mac, ethaddr, 6); ret = platform_device_register(&au1xxx_eth0_device); - if (!ret) + if (ret) printk(KERN_INFO "Alchemy: failed to register MAC0\n"); -- cgit v1.2.3 From 870168a031b3c5b78191d719d375221f01e98e11 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Tue, 2 Aug 2011 15:50:58 +0200 Subject: MIPS: Alchemy: Include Au1100 in PM code. The current code forgets the Au1100 when looking for the correct method to suspend the chip. Signed-off-by: Manuel Lauss To: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2675/ Signed-off-by: Ralf Baechle --- arch/mips/alchemy/common/power.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c index 647e518c90b..b86324a4260 100644 --- a/arch/mips/alchemy/common/power.c +++ b/arch/mips/alchemy/common/power.c @@ -158,15 +158,21 @@ static void restore_core_regs(void) void au_sleep(void) { - int cpuid = alchemy_get_cputype(); - if (cpuid != ALCHEMY_CPU_UNKNOWN) { - save_core_regs(); - if (cpuid <= ALCHEMY_CPU_AU1500) - alchemy_sleep_au1000(); - else if (cpuid <= ALCHEMY_CPU_AU1200) - alchemy_sleep_au1550(); - restore_core_regs(); + save_core_regs(); + + switch (alchemy_get_cputype()) { + case ALCHEMY_CPU_AU1000: + case ALCHEMY_CPU_AU1500: + case ALCHEMY_CPU_AU1100: + alchemy_sleep_au1000(); + break; + case ALCHEMY_CPU_AU1550: + case ALCHEMY_CPU_AU1200: + alchemy_sleep_au1550(); + break; } + + restore_core_regs(); } #endif /* CONFIG_PM */ -- cgit v1.2.3 From d954ffe34a606d4ec34cd3c2b0b5974779759f25 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 2 Aug 2011 22:52:48 +0100 Subject: MIPS: tlbex: Fix build error in R3000 code. Only some GCC versions such as gcc 4.2 notice that the variable wr in build_r3000_tlb_modify_handler is used uninitialized. When using one of those GCCs the build will fail due to -Werror. GCC 4.6 does not warn about the uninitialized use of wr. This issue was introduced by 7211f4d7a3dcbe57c5d396c334dca525315dceb2 [MIPS: Close races in TLB modify handlers.] Reported-by: Ganesan Ramalingam Signed-off-by: Ralf Baechle --- arch/mips/mm/tlbex.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index b6e1cff5066..46f33c7c1a0 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -1759,14 +1759,13 @@ static void __cpuinit build_r3000_tlb_modify_handler(void) u32 *p = handle_tlbm; struct uasm_label *l = labels; struct uasm_reloc *r = relocs; - struct work_registers wr; memset(handle_tlbm, 0, sizeof(handle_tlbm)); memset(labels, 0, sizeof(labels)); memset(relocs, 0, sizeof(relocs)); build_r3000_tlbchange_handler_head(&p, K0, K1); - build_pte_modifiable(&p, &r, wr.r1, wr.r2, wr.r3, label_nopage_tlbm); + build_pte_modifiable(&p, &r, K0, K1, -1, label_nopage_tlbm); uasm_i_nop(&p); /* load delay */ build_make_write(&p, &r, K0, K1); build_r3000_pte_reload_tlbwi(&p, K0, K1); -- cgit v1.2.3 From 77fbdb30f045084f1c65b72bd457d7406343aad7 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 18 Jul 2011 18:08:40 +0200 Subject: MIPS: Lantiq: Fix external interrupt sources The irq base offset needs to be ignored when matching irqs to external interrupt pins. Taking the offset into account resulted in the EIU not being brought up properly. Signed-off-by: John Crispin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2616/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/irq.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c index fc89795cafd..f9737bb3c5a 100644 --- a/arch/mips/lantiq/irq.c +++ b/arch/mips/lantiq/irq.c @@ -123,11 +123,10 @@ void ltq_enable_irq(struct irq_data *d) static unsigned int ltq_startup_eiu_irq(struct irq_data *d) { int i; - int irq_nr = d->irq - INT_NUM_IRQ0; ltq_enable_irq(d); for (i = 0; i < MAX_EIU; i++) { - if (irq_nr == ltq_eiu_irq[i]) { + if (d->irq == ltq_eiu_irq[i]) { /* low level - we should really handle set_type */ ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_C) | (0x6 << (i * 4)), LTQ_EIU_EXIN_C); @@ -147,11 +146,10 @@ static unsigned int ltq_startup_eiu_irq(struct irq_data *d) static void ltq_shutdown_eiu_irq(struct irq_data *d) { int i; - int irq_nr = d->irq - INT_NUM_IRQ0; ltq_disable_irq(d); for (i = 0; i < MAX_EIU; i++) { - if (irq_nr == ltq_eiu_irq[i]) { + if (d->irq == ltq_eiu_irq[i]) { /* disable */ ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~(1 << i), LTQ_EIU_EXIN_INEN); -- cgit v1.2.3 From 0596954681859f1b7b7adfd58fa738c09ed2affa Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 18 Jul 2011 18:04:12 +0200 Subject: MIPS: Lantiq: Fix setting the PCI bus speed on AR9 The bits used to set the PCI bus speed on AR9 are slightly different to those used on Danube. Signed-off-by: John Crispin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2614/ Signed-off-by: Ralf Baechle --- arch/mips/pci/pci-lantiq.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/mips/pci/pci-lantiq.c b/arch/mips/pci/pci-lantiq.c index 603d7493e96..8656388b34b 100644 --- a/arch/mips/pci/pci-lantiq.c +++ b/arch/mips/pci/pci-lantiq.c @@ -171,8 +171,13 @@ static int __devinit ltq_pci_startup(struct ltq_pci_data *conf) u32 temp_buffer; /* set clock to 33Mhz */ - ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~0xf00000, LTQ_CGU_IFCCR); - ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | 0x800000, LTQ_CGU_IFCCR); + if (ltq_is_ar9()) { + ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~0x1f00000, LTQ_CGU_IFCCR); + ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | 0xe00000, LTQ_CGU_IFCCR); + } else { + ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~0xf00000, LTQ_CGU_IFCCR); + ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | 0x800000, LTQ_CGU_IFCCR); + } /* external or internal clock ? */ if (conf->clock) { -- cgit v1.2.3 From b7867f1bfcb76c75d98d35f576fcd9d7759a96fe Mon Sep 17 00:00:00 2001 From: John Crispin Date: Wed, 3 Aug 2011 13:37:24 +0100 Subject: SERIAL: Lantiq: Set timeout in uart_port Without this patch apps using readline hang. Signed-off-by: Thomas Langer Signed-off-by: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-serial@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/2687/ Signed-off-by: Alan Cox Signed-off-by: Ralf Baechle --- drivers/tty/serial/lantiq.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index 58cf279ed87..bc95f52cad8 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c @@ -478,8 +478,10 @@ lqasc_set_termios(struct uart_port *port, spin_unlock_irqrestore(<q_asc_lock, flags); /* Don't rewrite B0 */ - if (tty_termios_baud_rate(new)) + if (tty_termios_baud_rate(new)) tty_termios_encode_baud_rate(new, baud, baud); + + uart_update_timeout(port, cflag, baud); } static const char* -- cgit v1.2.3 From dd0a028183369cccc0826199a7ccdc850ece289b Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Fri, 12 Aug 2011 08:28:35 +0200 Subject: MIPS: Alchemy: DB1200: Disable cascade IRQ in handler Disable the cascade IRQ in the cascade handler. This is required to get the DB1300 working, and also gets rid of all spurious interrupts previously observed on the DB1200; so Config[OD] can be disabled again for better performance. Signed-off-by: Manuel Lauss To: Linux-MIPS Patchwork: https://patchwork.linux-mips.org/patch/2708/ Signed-off-by: Ralf Baechle --- arch/mips/alchemy/devboards/bcsr.c | 4 ++++ arch/mips/alchemy/devboards/db1200/setup.c | 7 ------- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/arch/mips/alchemy/devboards/bcsr.c b/arch/mips/alchemy/devboards/bcsr.c index 596ad00e7f0..463d2c4d944 100644 --- a/arch/mips/alchemy/devboards/bcsr.c +++ b/arch/mips/alchemy/devboards/bcsr.c @@ -89,8 +89,12 @@ static void bcsr_csc_handler(unsigned int irq, struct irq_desc *d) { unsigned short bisr = __raw_readw(bcsr_virt + BCSR_REG_INTSTAT); + disable_irq_nosync(irq); + for ( ; bisr; bisr &= bisr - 1) generic_handle_irq(bcsr_csc_base + __ffs(bisr)); + + enable_irq(irq); } /* NOTE: both the enable and mask bits must be cleared, otherwise the diff --git a/arch/mips/alchemy/devboards/db1200/setup.c b/arch/mips/alchemy/devboards/db1200/setup.c index 1dac4f27d33..4a8980027ec 100644 --- a/arch/mips/alchemy/devboards/db1200/setup.c +++ b/arch/mips/alchemy/devboards/db1200/setup.c @@ -23,13 +23,6 @@ void __init board_setup(void) unsigned long freq0, clksrc, div, pfc; unsigned short whoami; - /* Set Config[OD] (disable overlapping bus transaction): - * This gets rid of a _lot_ of spurious interrupts (especially - * wrt. IDE); but incurs ~10% performance hit in some - * cpu-bound applications. - */ - set_c0_config(1 << 19); - bcsr_init(DB1200_BCSR_PHYS_ADDR, DB1200_BCSR_PHYS_ADDR + DB1200_BCSR_HEXLED_OFS); -- cgit v1.2.3 From b8ecf341f1b7ca7bf3cb80c48cbbae33b79947d0 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Mon, 15 Aug 2011 13:07:05 -0400 Subject: MIPS: Do not use EXTRA_CFLAGS Usage of these flags has been deprecated for nearly 4 years by: commit f77bf01425b11947eeb3b5b54685212c302741b8 Author: Sam Ravnborg Date: Mon Oct 15 22:25:06 2007 +0200 kbuild: introduce ccflags-y, asflags-y and ldflags-y Moreover, these flags (at least EXTRA_CFLAGS) have been documented for command line use. By default, gmake(1) do not override command line setting, so this is likely to result in build failure or unexpected behavior. Replace their usage by Kbuild's `{as,cc,ld}flags-y'. To: linux-kernel@vger.kernel.org Cc: Sam Ravnborg Patchwork: https://patchwork.linux-mips.org/patch/2710/ Cc: linux-mips@linux-mips.org Signed-off-by: Arnaud Lacombe Signed-off-by: Ralf Baechle --- arch/mips/netlogic/xlr/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/netlogic/xlr/Makefile b/arch/mips/netlogic/xlr/Makefile index 9bd3f731f62..2dca585dd2f 100644 --- a/arch/mips/netlogic/xlr/Makefile +++ b/arch/mips/netlogic/xlr/Makefile @@ -2,4 +2,4 @@ obj-y += setup.o platform.o irq.o setup.o time.o obj-$(CONFIG_SMP) += smp.o smpboot.o obj-$(CONFIG_EARLY_PRINTK) += xlr_console.o -EXTRA_CFLAGS += -Werror +ccflags-y += -Werror -- cgit v1.2.3 From 1eec6cd08b4feb72a73aff468ab72bdd21e1dc61 Mon Sep 17 00:00:00 2001 From: Yong Zhang Date: Tue, 16 Aug 2011 09:54:54 +0800 Subject: MIPS: Compat: Use 32-bit wrapper for compat_sys_futex. We can't trust userspace to pass signed-extend arguments. Not correctly sign-extended arguments to futex-wait result in architecturally undefined operation of 32-bit arithmetic instructions. For example, if 'val' is too big and bit-31 is 1, the caller may enter endless loop at: futex_wait_setup() { ... if (uval != val) { queue_unlock(q, *hb); ret = -EWOULDBLOCK; ... } Signed-off-by: Yong Zhang To: linux-mips@linux-mips.org To: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/2714/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/linux32.c | 7 +++++++ arch/mips/kernel/scall64-n32.S | 2 +- arch/mips/kernel/scall64-o32.S | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 876a75cc376..922a554cd10 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -349,3 +349,10 @@ SYSCALL_DEFINE6(32_fanotify_mark, int, fanotify_fd, unsigned int, flags, return sys_fanotify_mark(fanotify_fd, flags, merge_64(a3, a4), dfd, pathname); } + +SYSCALL_DEFINE6(32_futex, u32 __user *, uaddr, int, op, u32, val, + struct compat_timespec __user *, utime, u32 __user *, uaddr2, + u32, val3) +{ + return compat_sys_futex(uaddr, op, val, utime, uaddr2, val3); +} diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index f9296e894e4..6de1f598346 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -315,7 +315,7 @@ EXPORT(sysn32_call_table) PTR sys_fremovexattr PTR sys_tkill PTR sys_ni_syscall - PTR compat_sys_futex + PTR sys_32_futex PTR compat_sys_sched_setaffinity /* 6195 */ PTR compat_sys_sched_getaffinity PTR sys_cacheflush diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 4d7c9827706..1d813169e45 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -441,7 +441,7 @@ sys_call_table: PTR sys_fremovexattr /* 4235 */ PTR sys_tkill PTR sys_sendfile64 - PTR compat_sys_futex + PTR sys_32_futex PTR compat_sys_sched_setaffinity PTR compat_sys_sched_getaffinity /* 4240 */ PTR compat_sys_io_setup -- cgit v1.2.3 From bd7100099a46b59f433dd15ad60adbb4d4f3d625 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 2 Jun 2011 21:06:48 +0200 Subject: MIPS: PM: Use struct syscore_ops instead of sysdevs for PM (v2) Convert some MIPS architecture's code to using struct syscore_ops objects for power management instead of sysdev classes and sysdevs. This simplifies the code and reduces the kernel's memory footprint. It also is necessary for removing sysdevs from the kernel entirely in the future. Signed-off-by: Rafael J. Wysocki Acked-by: Greg Kroah-Hartman Acked-and-tested-by: Lars-Peter Clausen Signed-off-by: Lars-Peter Clausen Cc: linux-kernel@vger.kernel.org Cc: "Rafael J. Wysocki" Patchwork: http://patchwork.linux-mips.org/patch/2431/ Signed-off-by: Ralf Baechle --- arch/mips/jz4740/gpio.c | 52 +++++++++++++++++++++---------------------------- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/arch/mips/jz4740/gpio.c b/arch/mips/jz4740/gpio.c index 73031f7fc82..4397972949f 100644 --- a/arch/mips/jz4740/gpio.c +++ b/arch/mips/jz4740/gpio.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include #include @@ -86,7 +86,6 @@ struct jz_gpio_chip { spinlock_t lock; struct gpio_chip gpio_chip; - struct sys_device sysdev; }; static struct jz_gpio_chip jz4740_gpio_chips[]; @@ -459,49 +458,47 @@ static struct jz_gpio_chip jz4740_gpio_chips[] = { JZ4740_GPIO_CHIP(D), }; -static inline struct jz_gpio_chip *sysdev_to_chip(struct sys_device *dev) +static void jz4740_gpio_suspend_chip(struct jz_gpio_chip *chip) { - return container_of(dev, struct jz_gpio_chip, sysdev); + chip->suspend_mask = readl(chip->base + JZ_REG_GPIO_MASK); + writel(~(chip->wakeup), chip->base + JZ_REG_GPIO_MASK_SET); + writel(chip->wakeup, chip->base + JZ_REG_GPIO_MASK_CLEAR); } -static int jz4740_gpio_suspend(struct sys_device *dev, pm_message_t state) +static int jz4740_gpio_suspend(void) { - struct jz_gpio_chip *chip = sysdev_to_chip(dev); + int i; - chip->suspend_mask = readl(chip->base + JZ_REG_GPIO_MASK); - writel(~(chip->wakeup), chip->base + JZ_REG_GPIO_MASK_SET); - writel(chip->wakeup, chip->base + JZ_REG_GPIO_MASK_CLEAR); + for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); i++) + jz4740_gpio_suspend_chip(&jz4740_gpio_chips[i]); return 0; } -static int jz4740_gpio_resume(struct sys_device *dev) +static void jz4740_gpio_resume_chip(struct jz_gpio_chip *chip) { - struct jz_gpio_chip *chip = sysdev_to_chip(dev); uint32_t mask = chip->suspend_mask; writel(~mask, chip->base + JZ_REG_GPIO_MASK_CLEAR); writel(mask, chip->base + JZ_REG_GPIO_MASK_SET); +} - return 0; +static void jz4740_gpio_resume(void) +{ + int i; + + for (i = ARRAY_SIZE(jz4740_gpio_chips) - 1; i >= 0 ; i--) + jz4740_gpio_resume_chip(&jz4740_gpio_chips[i]); } -static struct sysdev_class jz4740_gpio_sysdev_class = { - .name = "gpio", +static struct syscore_ops jz4740_gpio_syscore_ops = { .suspend = jz4740_gpio_suspend, .resume = jz4740_gpio_resume, }; -static int jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id) +static void jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id) { - int ret, irq; - - chip->sysdev.id = id; - chip->sysdev.cls = &jz4740_gpio_sysdev_class; - ret = sysdev_register(&chip->sysdev); - - if (ret) - return ret; + int irq; spin_lock_init(&chip->lock); @@ -519,22 +516,17 @@ static int jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id) irq_set_chip_and_handler(irq, &jz_gpio_irq_chip, handle_level_irq); } - - return 0; } static int __init jz4740_gpio_init(void) { unsigned int i; - int ret; - - ret = sysdev_class_register(&jz4740_gpio_sysdev_class); - if (ret) - return ret; for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i) jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i); + register_syscore_ops(&jz4740_gpio_syscore_ops); + printk(KERN_INFO "JZ4740 GPIO initialized\n"); return 0; -- cgit v1.2.3 From 465aaed0030b23d905f3eca5e65481773bea9ea1 Mon Sep 17 00:00:00 2001 From: David Daney Date: Sat, 20 Aug 2011 08:44:00 -0700 Subject: MIPS: Octeon: Select CONFIG_HOLES_IN_ZONE Current Octeon systems do in fact have holes in their memory zones. We need to select HOLES_IN_ZONE. If we do not, some memory configurations will result in crashes at boot time like this: . . . CPU 6 Unable to handle kernel paging request at virtual address 0000000000700000, epc == ffffffff8118fe00, ra == ffffffff8118fe9c Oops[#1]: Cpu 6 . . . ... Call Trace: [] setup_per_zone_wmarks+0x1b0/0x338 [] init_per_zone_wmark_min+0x64/0xd0 [] do_one_initcall+0x38/0x160 . . . Reported-by: Jason Kwon Signed-off-by: David Daney To: linux-mips@linux-mips.org Cc: Jason Kwon Patchwork: https://patchwork.linux-mips.org/patch/2724/ Tested-by: Guenter Roeck Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index d300c2bf836..b122adc8bdb 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -723,6 +723,7 @@ config CAVIUM_OCTEON_SIMULATOR select SYS_SUPPORTS_HIGHMEM select SYS_SUPPORTS_HOTPLUG_CPU select SYS_HAS_CPU_CAVIUM_OCTEON + select HOLES_IN_ZONE help The Octeon simulator is software performance model of the Cavium Octeon Processor. It supports simulating Octeon processors on x86 @@ -745,6 +746,7 @@ config CAVIUM_OCTEON_REFERENCE_BOARD select ZONE_DMA32 select USB_ARCH_HAS_OHCI select USB_ARCH_HAS_EHCI + select HOLES_IN_ZONE help This option supports all of the Octeon reference boards from Cavium Networks. It builds a kernel that dynamically determines the Octeon @@ -974,6 +976,9 @@ config ISA_DMA_API config GENERIC_GPIO bool +config HOLES_IN_ZONE + bool + # # Endianess selection. Sufficiently obscure so many users don't know what to # answer,so we try hard to limit the available choices. Also the use of a -- cgit v1.2.3 From d968275921f9fa7fbc602ac6618ffec6a062ee3c Mon Sep 17 00:00:00 2001 From: David Daney Date: Tue, 30 Aug 2011 06:45:20 -0700 Subject: MIPS: Don't clobber CP0_STATUS value for CONFIG_MIPS_MT_SMTC Reported-by: Edgar E. Iglesias Signed-off-by: David Daney Patchwork: https://patchwork.linux-mips.org/patch/2753/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/stackframe.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h index b4ba2449444..cb41af5f340 100644 --- a/arch/mips/include/asm/stackframe.h +++ b/arch/mips/include/asm/stackframe.h @@ -195,9 +195,9 @@ * to cover the pipeline delay. */ .set mips32 - mfc0 v1, CP0_TCSTATUS + mfc0 k0, CP0_TCSTATUS .set mips0 - LONG_S v1, PT_TCSTATUS(sp) + LONG_S k0, PT_TCSTATUS(sp) #endif /* CONFIG_MIPS_MT_SMTC */ LONG_S $4, PT_R4(sp) LONG_S $5, PT_R5(sp) -- cgit v1.2.3 From 0f4ccbc835036cbcc2513585bb2e93ee62e12674 Mon Sep 17 00:00:00 2001 From: David Daney Date: Fri, 16 Sep 2011 18:06:02 -0700 Subject: MIPS: No branches in delay slots for huge pages in handle_tlbl For the case PM_DEFAULT_MASK == 0, we were placing a branch in the delay slot of another branch. This leads to undefined behavior. Signed-off-by: David Daney Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2775/ Signed-off-by: Ralf Baechle --- arch/mips/mm/tlbex.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 46f33c7c1a0..e06370f58ef 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -1962,7 +1962,8 @@ static void __cpuinit build_r4000_tlb_load_handler(void) uasm_i_andi(&p, wr.r3, wr.r3, 2); uasm_il_beqz(&p, &r, wr.r3, label_tlbl_goaround2); } - + if (PM_DEFAULT_MASK == 0) + uasm_i_nop(&p); /* * We clobbered C0_PAGEMASK, restore it. On the other branch * it is restored in build_huge_tlb_write_entry. -- cgit v1.2.3 From 2f19d080fb14bdddf11bf54d4db6306235c46c99 Mon Sep 17 00:00:00 2001 From: David Daney Date: Tue, 5 Jul 2011 16:35:53 -0700 Subject: MIPS: Octeon: Enable C0_UserLocal probing. Octeon2 processor cores have a UserLocal register. Remove the hard coded negative probe and allow the standard probing to detect this feature. Signed-off-by: David Daney To: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2578/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h index 0d5a42b5f47..a58addb98cf 100644 --- a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h @@ -54,7 +54,6 @@ #define cpu_has_mips_r2_exec_hazard 0 #define cpu_has_dsp 0 #define cpu_has_mipsmt 0 -#define cpu_has_userlocal 0 #define cpu_has_vint 0 #define cpu_has_veic 0 #define cpu_hwrena_impl_bits 0xc0000000 -- cgit v1.2.3 From a4be637b34a543af5b5421a8ee0ee04d30f5f58e Mon Sep 17 00:00:00 2001 From: "Roy.Li" Date: Mon, 26 Sep 2011 09:08:00 +0800 Subject: staging/octeon: Software should check the checksum of no tcp/udp packets Icmp packets with wrong checksum are never dropped since skb->ip_summed is set to CHECKSUM_UNNECESSARY. When icmp packets with wrong checksum pass through the octeon net driver, the not_IP, IP_exc, L4_error hardware indicators show no error. so the driver sets CHECKSUM_UNNECESSARY on skb->ip_summed. L4_error only works for TCP/UDP, not for ICMP. Signed-off-by: Roy.Li To: linux-mips@linux-mips.org Cc: netdev@vger.kernel.org Cc: ralf@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2798/ Acked-by: David Daney Cc: Greg KH --- drivers/staging/octeon/ethernet-rx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c index 1a7c19ae766..8b307b42879 100644 --- a/drivers/staging/octeon/ethernet-rx.c +++ b/drivers/staging/octeon/ethernet-rx.c @@ -411,7 +411,8 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) skb->protocol = eth_type_trans(skb, dev); skb->dev = dev; - if (unlikely(work->word2.s.not_IP || work->word2.s.IP_exc || work->word2.s.L4_error)) + if (unlikely(work->word2.s.not_IP || work->word2.s.IP_exc || + work->word2.s.L4_error || !work->word2.s.tcp_or_udp)) skb->ip_summed = CHECKSUM_NONE; else skb->ip_summed = CHECKSUM_UNNECESSARY; -- cgit v1.2.3 From 3696d303d6a39f916f9ace37d79e3db7937c68a7 Mon Sep 17 00:00:00 2001 From: Bryan Buckley Date: Fri, 30 Sep 2011 11:05:55 -0700 Subject: ARM: OMAP4: MMC: fix power and audio issue, decouple USBC1 from MMC1 Remove OMAP4_USBC1_ICUSB_PWRDNZ_MASK during enable/disable PWRDNZ mode for MMC1_PBIAS and associated extended-drain MMC1 I/O cell. This is in accordance with the control module programming guide. This fixes a bug where if trying to use gpio_98 or gpio_99 and MMC1 at the same time the GPIO signal will be affected by a changing SDMMC1_VDDS. Software must keep MMC1_PBIAS cell and MMC1_IO cell PWRDNZ signals low whenever SDMMC1_VDDS ramps up/down or changes for cell protection purposes. MMC1 is based on SDMMC1_VDDS whereas USBC1 is based on SIM_VDDS therefore they can operate independently. Signed-off-by: Bryan Buckley Acked-by: Kishore Kadiyala Tested-by: Balaji T K Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/hsmmc.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index a9b45c76e1d..097a42d81e5 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -137,8 +137,7 @@ static void omap4_hsmmc1_before_set_reg(struct device *dev, int slot, */ reg = omap4_ctrl_pad_readl(control_pbias_offset); reg &= ~(OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK | - OMAP4_MMC1_PWRDNZ_MASK | - OMAP4_USBC1_ICUSB_PWRDNZ_MASK); + OMAP4_MMC1_PWRDNZ_MASK); omap4_ctrl_pad_writel(reg, control_pbias_offset); } @@ -156,8 +155,7 @@ static void omap4_hsmmc1_after_set_reg(struct device *dev, int slot, else reg |= OMAP4_MMC1_PBIASLITE_VMODE_MASK; reg |= (OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK | - OMAP4_MMC1_PWRDNZ_MASK | - OMAP4_USBC1_ICUSB_PWRDNZ_MASK); + OMAP4_MMC1_PWRDNZ_MASK); omap4_ctrl_pad_writel(reg, control_pbias_offset); timeout = jiffies + msecs_to_jiffies(5); @@ -171,16 +169,14 @@ static void omap4_hsmmc1_after_set_reg(struct device *dev, int slot, if (reg & OMAP4_MMC1_PBIASLITE_VMODE_ERROR_MASK) { pr_err("Pbias Voltage is not same as LDO\n"); /* Caution : On VMODE_ERROR Power Down MMC IO */ - reg &= ~(OMAP4_MMC1_PWRDNZ_MASK | - OMAP4_USBC1_ICUSB_PWRDNZ_MASK); + reg &= ~(OMAP4_MMC1_PWRDNZ_MASK); omap4_ctrl_pad_writel(reg, control_pbias_offset); } } else { reg = omap4_ctrl_pad_readl(control_pbias_offset); reg |= (OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK | OMAP4_MMC1_PWRDNZ_MASK | - OMAP4_MMC1_PBIASLITE_VMODE_MASK | - OMAP4_USBC1_ICUSB_PWRDNZ_MASK); + OMAP4_MMC1_PBIASLITE_VMODE_MASK); omap4_ctrl_pad_writel(reg, control_pbias_offset); } } -- cgit v1.2.3 From bfd46a543f8f90bb197225900e355ce3c7daeb1f Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 30 Sep 2011 11:05:55 -0700 Subject: ARM: OMAP: Fix i2c init for twl4030 Looks like 2600 kHz rate does not work reliably on 2430, so just use the 100 kHz rate. Otherwise the system often fails to boot properly with: omap_i2c omap_i2c.2: timeout waiting for bus ready omap_i2c omap_i2c.2: timeout waiting for bus ready twl: i2c_write failed to transfer all messages omap_i2c omap_i2c.2: timeout waiting for bus ready twl: i2c_write failed to transfer all messages omap_i2c omap_i2c.2: timeout waiting for bus ready twl: i2c_write failed to transfer all messages twl: clock init err [-110] omap_i2c omap_i2c.2: timeout waiting for bus ready twl: i2c_write failed to transfer all messages TWL4030 Unable to unlock IDCODE registers --110 Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-2430sdp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index 2028464cf5b..f79b7d2a8ed 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -193,7 +193,8 @@ static int __init omap2430_i2c_init(void) { omap_register_i2c_bus(1, 100, sdp2430_i2c1_boardinfo, ARRAY_SIZE(sdp2430_i2c1_boardinfo)); - omap2_pmic_init("twl4030", &sdp2430_twldata); + omap_pmic_init(2, 100, "twl4030", INT_24XX_SYS_NIRQ, + &sdp2430_twldata); return 0; } -- cgit v1.2.3 From b8e111a74d281b70e88bd67fec48cfda4f9bdce2 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 30 Sep 2011 11:05:55 -0700 Subject: ARM: OMAP: musb: Remove a redundant omap4430_phy_init call in usb_musb_init Current code calls omap4430_phy_init() twice in usb_musb_init(). Calling omap4430_phy_init() once is enough. This patch removes the first omap4430_phy_init() call, which using an uninitialized pointer as parameter. This patch elimates below build warning: arch/arm/mach-omap2/usb-musb.c: In function 'usb_musb_init': arch/arm/mach-omap2/usb-musb.c:141: warning: 'dev' may be used uninitialized in this function Signed-off-by: Axel Lin Bjarne Steinsbo Acked-by: Felipe Balbi Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/usb-musb.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c index a65145b02a5..19e4dac62a8 100644 --- a/arch/arm/mach-omap2/usb-musb.c +++ b/arch/arm/mach-omap2/usb-musb.c @@ -137,9 +137,6 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data) musb_plat.mode = board_data->mode; musb_plat.extvbus = board_data->extvbus; - if (cpu_is_omap44xx()) - omap4430_phy_init(dev); - if (cpu_is_omap3517() || cpu_is_omap3505()) { oh_name = "am35x_otg_hs"; name = "musb-am35x"; -- cgit v1.2.3 From 002ea9eefec98dada56fd5f8e432a4e8570c2a26 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 29 Sep 2011 09:37:23 +0100 Subject: ARM: 7113/1: mm: Align bank start to MAX_ORDER_NR_PAGES The VM subsystem assumes that there are valid memmap entries from the bank start aligned to MAX_ORDER_NR_PAGES. On the Ux500 we have a lot of mem=N arguments on the commandline triggering this bug several times over and causing kernel oops messages. Cc: stable@kernel.org Cc: Michael Bohan Cc: Nicolas Pitre Signed-off-by: Johan Palsson Signed-off-by: Rabin Vincent Signed-off-by: Linus Walleij Signed-off-by: Russell King --- arch/arm/mm/init.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index cc7e2d8be9a..f8037ba338a 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -496,6 +496,13 @@ static void __init free_unused_memmap(struct meminfo *mi) */ bank_start = min(bank_start, ALIGN(prev_bank_end, PAGES_PER_SECTION)); +#else + /* + * Align down here since the VM subsystem insists that the + * memmap entries are valid from the bank start aligned to + * MAX_ORDER_NR_PAGES. + */ + bank_start = round_down(bank_start, MAX_ORDER_NR_PAGES); #endif /* * If we had a previous bank, and there is a space -- cgit v1.2.3 From 8742cd23471635f8b069bf9a6806200a77397ddb Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Fri, 30 Sep 2011 13:49:35 -0500 Subject: MIPS: Call oops_enter, oops_exit in die This allows pause_on_oops and mtdoops to work. Signed-off-by: Nathan Lynch To: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2810/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/traps.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 01eff7e609e..cbea618af0b 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -371,14 +372,19 @@ void __noreturn die(const char *str, struct pt_regs *regs) static int die_counter; int sig = SIGSEGV; #ifdef CONFIG_MIPS_MT_SMTC - unsigned long dvpret = dvpe(); + unsigned long dvpret; #endif /* CONFIG_MIPS_MT_SMTC */ + oops_enter(); + if (notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV) == NOTIFY_STOP) sig = 0; console_verbose(); raw_spin_lock_irq(&die_lock); +#ifdef CONFIG_MIPS_MT_SMTC + dvpret = dvpe(); +#endif /* CONFIG_MIPS_MT_SMTC */ bust_spinlocks(1); #ifdef CONFIG_MIPS_MT_SMTC mips_mt_regdump(dvpret); @@ -389,6 +395,8 @@ void __noreturn die(const char *str, struct pt_regs *regs) add_taint(TAINT_DIE); raw_spin_unlock_irq(&die_lock); + oops_exit(); + if (in_interrupt()) panic("Fatal exception in interrupt"); -- cgit v1.2.3 From 98d9ae841ad620045d653fb05764e4a899f42dbd Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Fri, 30 Sep 2011 16:38:29 +0200 Subject: netfilter: nf_conntrack: fix event flooding in GRE protocol tracker GRE connections cause ctnetlink event flood because the ASSURED event is set for every packet received. Reported-by: Denys Fedoryshchenko Tested-by: Denys Fedoryshchenko Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_proto_gre.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c index cf616e55ca4..d69facdd9a7 100644 --- a/net/netfilter/nf_conntrack_proto_gre.c +++ b/net/netfilter/nf_conntrack_proto_gre.c @@ -241,8 +241,8 @@ static int gre_packet(struct nf_conn *ct, nf_ct_refresh_acct(ct, ctinfo, skb, ct->proto.gre.stream_timeout); /* Also, more likely to be important, and not a probe. */ - set_bit(IPS_ASSURED_BIT, &ct->status); - nf_conntrack_event_cache(IPCT_ASSURED, ct); + if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status)) + nf_conntrack_event_cache(IPCT_ASSURED, ct); } else nf_ct_refresh_acct(ct, ctinfo, skb, ct->proto.gre.timeout); -- cgit v1.2.3 From 4f332844cc87c5f99c5300f788abbe8a8c731390 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 4 Oct 2011 17:23:15 -0400 Subject: drm/radeon/kms: retry aux transactions if there are status flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If there are error flags in the aux status, retry the transaction. This makes aux much more reliable, especially on llano systems. Signed-off-by: Alex Deucher Reviewed-by: Michel Dänzer Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/atombios_dp.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 4da23889fea..79e8ebc0530 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -129,7 +129,9 @@ static int radeon_dp_aux_native_write(struct radeon_connector *radeon_connector, for (retry = 0; retry < 4; retry++) { ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_bytes, NULL, 0, delay, &ack); - if (ret < 0) + if (ret == -EBUSY) + continue; + else if (ret < 0) return ret; if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) return send_bytes; @@ -160,7 +162,9 @@ static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, for (retry = 0; retry < 4; retry++) { ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_bytes, recv, recv_bytes, delay, &ack); - if (ret < 0) + if (ret == -EBUSY) + continue; + else if (ret < 0) return ret; if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) return ret; @@ -236,7 +240,9 @@ int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, for (retry = 0; retry < 4; retry++) { ret = radeon_process_aux_ch(auxch, msg, msg_bytes, reply, reply_bytes, 0, &ack); - if (ret < 0) { + if (ret == -EBUSY) + continue; + else if (ret < 0) { DRM_DEBUG_KMS("aux_ch failed %d\n", ret); return ret; } -- cgit v1.2.3 From 6777a4f6898a53974ef7fe7ce09ec41fae0f32db Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 4 Oct 2011 12:23:24 -0400 Subject: drm/radeon/kms: fix dp_detect handling for DP bridge chips MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The HPD pin is not reliable for detecting whether a monitor is connected or not. Skip HPD and just use DDC or load detection. Fixes phantom VGA connected bugs. [Michel: fixes phantom VGA bugs on his llano system.] Signed-off-by: Alex Deucher Reviewed-by: Michel Dänzer Tested-by: Michel Dänzer Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_connectors.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index bce63fd329d..449c3d8c683 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -1303,23 +1303,14 @@ radeon_dp_detect(struct drm_connector *connector, bool force) /* get the DPCD from the bridge */ radeon_dp_getdpcd(radeon_connector); - if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) - ret = connector_status_connected; - else { - /* need to setup ddc on the bridge */ - if (encoder) - radeon_atom_ext_encoder_setup_ddc(encoder); + if (encoder) { + /* setup ddc on the bridge */ + radeon_atom_ext_encoder_setup_ddc(encoder); if (radeon_ddc_probe(radeon_connector, - radeon_connector->requires_extended_probe)) + radeon_connector->requires_extended_probe)) /* try DDC */ ret = connector_status_connected; - } - - if ((ret == connector_status_disconnected) && - radeon_connector->dac_load_detect) { - struct drm_encoder *encoder = radeon_best_single_encoder(connector); - struct drm_encoder_helper_funcs *encoder_funcs; - if (encoder) { - encoder_funcs = encoder->helper_private; + else if (radeon_connector->dac_load_detect) { /* try load detection */ + struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; ret = encoder_funcs->detect(encoder, connector); } } -- cgit v1.2.3 From cb7cf41961fe10773c491c75ae73539ad4bbed66 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 5 Oct 2011 18:36:50 -0400 Subject: drm/radeon/kms: use hardcoded dig encoder to transmitter mapping for DCE4.1 The encoders are supposedly fully routeable, but changing the mapping doesn't always seem to take. Using a hardcoded mapping is much more reliable. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=41366 Signed-off-by: Alex Deucher Tested-by: Simon Farnsworth Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_encoders.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 13690f3eb4a..8a171b21b45 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -1755,9 +1755,12 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) /* DCE4/5 */ if (ASIC_IS_DCE4(rdev)) { dig = radeon_encoder->enc_priv; - if (ASIC_IS_DCE41(rdev)) - return radeon_crtc->crtc_id; - else { + if (ASIC_IS_DCE41(rdev)) { + if (dig->linkb) + return 1; + else + return 0; + } else { switch (radeon_encoder->encoder_id) { case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: if (dig->linkb) -- cgit v1.2.3 From 98e87d57aab9b1594f9cc53a386fcb6f2f2ba6e2 Mon Sep 17 00:00:00 2001 From: srinidhi kasagar Date: Tue, 20 Sep 2011 11:15:46 +0530 Subject: ARM: mach-ux500: enable fix for ARM errata 754322 This applies ARM errata fix 754322 for all ux500 platforms. Cc: stable@kernel.org Signed-off-by: srinidhi kasagar Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 4210cb434db..a3e0c8692f0 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -6,6 +6,7 @@ config UX500_SOC_COMMON select ARM_GIC select HAS_MTU select ARM_ERRATA_753970 + select ARM_ERRATA_754322 menu "Ux500 SoC" -- cgit v1.2.3 From f22ed71cd60210d2f476986c0266004e4db45f34 Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Thu, 8 Sep 2011 03:11:15 +0000 Subject: sparc32,leon: SRMMU MMU Table probe fix The LEON MMU Model (SRMMU) does not implement MMu Table probing in hardware, instead it is implemented in software. However the software implementation does not return the PTE as it should which always results in INVALID entires and the PROM mappings are not inherited as they should during startup. The following patch removes the masking of the PTE. Signed-off-by: Daniel Hellstrom Signed-off-by: David S. Miller --- arch/sparc/include/asm/pgtsrmmu.h | 2 +- arch/sparc/mm/leon_mm.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/sparc/include/asm/pgtsrmmu.h b/arch/sparc/include/asm/pgtsrmmu.h index 1407c07bdad..f6ae2b2b687 100644 --- a/arch/sparc/include/asm/pgtsrmmu.h +++ b/arch/sparc/include/asm/pgtsrmmu.h @@ -280,7 +280,7 @@ static inline unsigned long srmmu_hwprobe(unsigned long vaddr) return retval; } #else -#define srmmu_hwprobe(addr) (srmmu_swprobe(addr, 0) & SRMMU_PTE_PMASK) +#define srmmu_hwprobe(addr) srmmu_swprobe(addr, 0) #endif static inline int diff --git a/arch/sparc/mm/leon_mm.c b/arch/sparc/mm/leon_mm.c index e485a680499..13c2169822a 100644 --- a/arch/sparc/mm/leon_mm.c +++ b/arch/sparc/mm/leon_mm.c @@ -162,7 +162,7 @@ ready: printk(KERN_INFO "swprobe: padde %x\n", paddr_calc); if (paddr) *paddr = paddr_calc; - return paddrbase; + return pte; } void leon_flush_icache_all(void) -- cgit v1.2.3 From 9d1e397b7bafe843564eab26ed3f682637159c6c Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 6 Oct 2011 23:14:07 -0500 Subject: [CIFS] Fix first time message on mount, ntlmv2 upgrade delayed to 3.2 Microsoft has a bug with ntlmv2 that requires use of ntlmssp, but we didn't get the required information on when/how to use ntlmssp to old (but once very popular) legacy servers (various NT4 fixpacks for example) until too late to merge for 3.1. Will upgrade to NTLMv2 in NTLMSSP in 3.2 Signed-off-by: Steve French Reviewed-by: Jeff Layton --- fs/cifs/connect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index f4af4cc3750..71beb020197 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2018,7 +2018,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) warned_on_ntlm = true; cERROR(1, "default security mechanism requested. The default " "security mechanism will be upgraded from ntlm to " - "ntlmv2 in kernel release 3.1"); + "ntlmv2 in kernel release 3.2"); } ses->overrideSecFlg = volume_info->secFlg; -- cgit v1.2.3 From 746fb63c54d2659e1da3c5e90a77ccb23a309cc5 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Fri, 7 Oct 2011 13:27:48 -0700 Subject: MAINTAINERS: Update tegra maintainer information A couple of changes to the Tegra maintainership setup: I'm very glad to bring on Stephen Warren on board as a maintainer. The work he has done so far is excellent, and the fact that he works for Nvidia means he has long-term interest in the platform. Erik Gilling did an astounding amount of work on getting things up and running but has been a silent partner on the maintainership side for a while, and is stepping down. Thanks for your contributions so far, Erik. Finally, update the git URL since I'll take over running the main repo for a while. Overall maintainership model isn't changing much at this time: We'll all three review patches as appropriate, and one of us will collect the main repo (me at this time). Signed-off-by: Olof Johansson Cc: Erik Gilling Acked-by: Colin Cross Acked-by: Stephen Warren Signed-off-by: Linus Torvalds --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index ace8f9c81b9..5483e0c93b4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6366,10 +6366,10 @@ F: net/ipv4/tcp_lp.c TEGRA SUPPORT M: Colin Cross -M: Erik Gilling M: Olof Johansson +M: Stephen Warren L: linux-tegra@vger.kernel.org -T: git git://android.git.kernel.org/kernel/tegra.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/olof/tegra.git S: Supported F: arch/arm/mach-tegra -- cgit v1.2.3 From 3faf12cd8603e3efbcc7e570e07dfd1ea2a17095 Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Fri, 7 Oct 2011 08:31:41 -0700 Subject: ARM: tegra: fix compilation error due to mach/hardware.h removal This fixes a compilation error in cpu-tegra.c which was introduced in dc8d966bccde ("ARM: convert PCI defines to variables") which removed the now obsolete mach/hardware.h from the mach-tegra subtree. Signed-off-by: Marc Dietrich Signed-off-by: Olof Johansson Cc: Sergei Shtylyov Signed-off-by: Linus Torvalds --- arch/arm/mach-tegra/cpu-tegra.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-tegra/cpu-tegra.c b/arch/arm/mach-tegra/cpu-tegra.c index 0e1016a827a..0e0fd4d889b 100644 --- a/arch/arm/mach-tegra/cpu-tegra.c +++ b/arch/arm/mach-tegra/cpu-tegra.c @@ -32,7 +32,6 @@ #include -#include #include /* Frequency table index must be sequential starting at 0 */ -- cgit v1.2.3 From c5d6136e10d667965e46f998c01863802f7b89c8 Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Mon, 10 Oct 2011 06:42:23 +0000 Subject: mlx4_en: fix endianness with blue frame support The doorbell register was being unconditionally swapped. In x86, that meant it was being swapped to BE and written to the descriptor and to memory, depending on the case of blue frame support or writing to doorbell register. On PPC, this meant it was being swapped to LE and then swapped back to BE while writing to the register. But in the blue frame case, it was being written as LE to the descriptor. The fix is not to swap doorbell unconditionally, write it to the register as BE and convert it to BE when writing it to the descriptor. Signed-off-by: Thadeu Lima de Souza Cascardo Reported-by: Richard Hendrickson Cc: Eli Cohen Cc: Yevgeny Petrilin Cc: Benjamin Herrenschmidt Signed-off-by: David S. Miller --- drivers/net/mlx4/en_tx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c index 6e03de034ac..f76ab6bf309 100644 --- a/drivers/net/mlx4/en_tx.c +++ b/drivers/net/mlx4/en_tx.c @@ -172,7 +172,7 @@ int mlx4_en_activate_tx_ring(struct mlx4_en_priv *priv, memset(ring->buf, 0, ring->buf_size); ring->qp_state = MLX4_QP_STATE_RST; - ring->doorbell_qpn = swab32(ring->qp.qpn << 8); + ring->doorbell_qpn = ring->qp.qpn << 8; mlx4_en_fill_qp_context(priv, ring->size, ring->stride, 1, 0, ring->qpn, ring->cqn, &ring->context); @@ -791,7 +791,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) skb_orphan(skb); if (ring->bf_enabled && desc_size <= MAX_BF && !bounce && !vlan_tag) { - *(u32 *) (&tx_desc->ctrl.vlan_tag) |= ring->doorbell_qpn; + *(__be32 *) (&tx_desc->ctrl.vlan_tag) |= cpu_to_be32(ring->doorbell_qpn); op_own |= htonl((bf_index & 0xffff) << 8); /* Ensure new descirptor hits memory * before setting ownership of this descriptor to HW */ @@ -812,7 +812,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) wmb(); tx_desc->ctrl.owner_opcode = op_own; wmb(); - writel(ring->doorbell_qpn, ring->bf.uar->map + MLX4_SEND_DOORBELL); + iowrite32be(ring->doorbell_qpn, ring->bf.uar->map + MLX4_SEND_DOORBELL); } /* Poll CQ here */ -- cgit v1.2.3 From 134d0f974c55c942541f1663d51fa846257eff2a Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Sun, 9 Oct 2011 23:57:36 +0000 Subject: bnx2x: fix cl_id allocation for non-eth clients for NPAR mode There are some consolidations of NPAR configuration when FCoE and iSCSI L2 clients will get the same id, in this case FCoE ring will be non-functional. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 18 ++++++++++++------ drivers/net/bnx2x/bnx2x_cmn.h | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index e46df5331c5..9a7eb3b36cf 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -239,13 +239,19 @@ void bnx2x_int_disable(struct bnx2x *bp); * FUNC_N_CLID_X = N * NUM_SPECIAL_CLIENTS + FUNC_0_CLID_X * */ -/* iSCSI L2 */ -#define BNX2X_ISCSI_ETH_CL_ID_IDX 1 -#define BNX2X_ISCSI_ETH_CID 49 +enum { + BNX2X_ISCSI_ETH_CL_ID_IDX, + BNX2X_FCOE_ETH_CL_ID_IDX, + BNX2X_MAX_CNIC_ETH_CL_ID_IDX, +}; -/* FCoE L2 */ -#define BNX2X_FCOE_ETH_CL_ID_IDX 2 -#define BNX2X_FCOE_ETH_CID 50 +#define BNX2X_CNIC_START_ETH_CID 48 +enum { + /* iSCSI L2 */ + BNX2X_ISCSI_ETH_CID = BNX2X_CNIC_START_ETH_CID, + /* FCoE L2 */ + BNX2X_FCOE_ETH_CID, +}; /** Additional rings budgeting */ #ifdef BCM_CNIC diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 223bfeebc59..2dc1199239d 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -1297,7 +1297,7 @@ static inline void bnx2x_init_txdata(struct bnx2x *bp, static inline u8 bnx2x_cnic_eth_cl_id(struct bnx2x *bp, u8 cl_idx) { return bp->cnic_base_cl_id + cl_idx + - (bp->pf_num >> 1) * NON_ETH_CONTEXT_USE; + (bp->pf_num >> 1) * BNX2X_MAX_CNIC_ETH_CL_ID_IDX; } static inline u8 bnx2x_cnic_fw_sb_id(struct bnx2x *bp) -- cgit v1.2.3 From cdaf557034bb4397b2c86bb424de1788b134f610 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Sat, 8 Oct 2011 22:34:35 +0000 Subject: gro: refetch inet6_protos[] after pulling ext headers ipv6_gro_receive() doesn't update the protocol ops after pulling the ext headers. It looks like a typo. Signed-off-by: Zheng Yan Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv6/af_inet6.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 3b5669a2582..d27c797f9f0 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -875,6 +875,7 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head, skb_reset_transport_header(skb); __skb_push(skb, skb_gro_offset(skb)); + ops = rcu_dereference(inet6_protos[proto]); if (!ops || !ops->gro_receive) goto out_unlock; -- cgit v1.2.3 From a3a4bfde8a271df7ee56fcf31b8d907d50e7f216 Mon Sep 17 00:00:00 2001 From: Wolfgang Grandegger Date: Fri, 7 Oct 2011 09:28:14 +0000 Subject: mscan: too much data copied to CAN frame due to 16 bit accesses Due to the 16 bit access to mscan registers there's too much data copied to the zero initialized CAN frame when having an odd number of bytes to copy. This patch ensures that only the requested bytes are copied by using an 8 bit access for the remaining byte. Reported-by: Andre Naujoks Signed-off-by: Oliver Hartkopp Signed-off-by: Wolfgang Grandegger Signed-off-by: David S. Miller --- drivers/net/can/mscan/mscan.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c index 92feac68b66..4cc6f44c2ba 100644 --- a/drivers/net/can/mscan/mscan.c +++ b/drivers/net/can/mscan/mscan.c @@ -261,11 +261,13 @@ static netdev_tx_t mscan_start_xmit(struct sk_buff *skb, struct net_device *dev) void __iomem *data = ®s->tx.dsr1_0; u16 *payload = (u16 *)frame->data; - /* It is safe to write into dsr[dlc+1] */ - for (i = 0; i < (frame->can_dlc + 1) / 2; i++) { + for (i = 0; i < frame->can_dlc / 2; i++) { out_be16(data, *payload++); data += 2 + _MSCAN_RESERVED_DSR_SIZE; } + /* write remaining byte if necessary */ + if (frame->can_dlc & 1) + out_8(data, frame->data[frame->can_dlc - 1]); } out_8(®s->tx.dlr, frame->can_dlc); @@ -330,10 +332,13 @@ static void mscan_get_rx_frame(struct net_device *dev, struct can_frame *frame) void __iomem *data = ®s->rx.dsr1_0; u16 *payload = (u16 *)frame->data; - for (i = 0; i < (frame->can_dlc + 1) / 2; i++) { + for (i = 0; i < frame->can_dlc / 2; i++) { *payload++ = in_be16(data); data += 2 + _MSCAN_RESERVED_DSR_SIZE; } + /* read remaining byte if necessary */ + if (frame->can_dlc & 1) + frame->data[frame->can_dlc - 1] = in_8(data); } out_8(®s->canrflg, MSCAN_RXF); -- cgit v1.2.3 From 2a0f7f5769992bae5b3f97157fd80b2b943be485 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Mon, 10 Oct 2011 15:43:34 -0400 Subject: Btrfs: fix recursive auto-defrag Follow those steps: # mount -o autodefrag /dev/sda7 /mnt # dd if=/dev/urandom of=/mnt/tmp bs=200K count=1 # sync # dd if=/dev/urandom of=/mnt/tmp bs=8K count=1 conv=notrunc and then it'll go into a loop: writeback -> defrag -> writeback ... It's because writeback writes [8K, 200K] and then writes [0, 8K]. I tried to make writeback know if the pages are dirtied by defrag, but the patch was a bit intrusive. Here I simply set writeback_index when we defrag a file. Signed-off-by: Li Zefan Signed-off-by: Chris Mason --- fs/btrfs/ioctl.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 6f89bcc4e55..df40b7c5f06 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -1055,6 +1055,13 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, if (!max_to_defrag) max_to_defrag = last_index - 1; + /* + * make writeback starts from i, so the defrag range can be + * written sequentially. + */ + if (i < inode->i_mapping->writeback_index) + inode->i_mapping->writeback_index = i; + while (i <= last_index && defrag_count < max_to_defrag) { /* * make sure we stop running if someone unmounts -- cgit v1.2.3 From 2b666859ec323403ac9a3a441d16eab30945404b Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 6 Oct 2011 00:40:47 +0300 Subject: x86: Default to vsyscall=native for now This UML breakage: linux-2.6.30.1[3800] vsyscall fault (exploit attempt?) ip:ffffffffff600000 cs:33 sp:7fbfb9c498 ax:ffffffffff600000 si:0 di:606790 linux-2.6.30.1[3856] vsyscall fault (exploit attempt?) ip:ffffffffff600000 cs:33 sp:7fbfb13168 ax:ffffffffff600000 si:0 di:606790 Is caused by commit 3ae36655 ("x86-64: Rework vsyscall emulation and add vsyscall= parameter") - the vsyscall emulation code is not fully cooked yet as UML relies on some rather fragile SIGSEGV semantics. Linus suggested in https://lkml.org/lkml/2011/8/9/376 to default to vsyscall=native for now, this patch implements that. Signed-off-by: Adrian Bunk Acked-by: Andrew Lutomirski Cc: H. Peter Anvin Link: http://lkml.kernel.org/r/20111005214047.GE14406@localhost.pp.htv.fi Signed-off-by: Ingo Molnar --- Documentation/kernel-parameters.txt | 7 ++++--- arch/x86/kernel/vsyscall_64.c | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 854ed5ca7e3..d6e6724446c 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -2706,10 +2706,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. functions are at fixed addresses, they make nice targets for exploits that can control RIP. - emulate [default] Vsyscalls turn into traps and are - emulated reasonably safely. + emulate Vsyscalls turn into traps and are emulated + reasonably safely. - native Vsyscalls are native syscall instructions. + native [default] Vsyscalls are native syscall + instructions. This is a little bit faster than trapping and makes a few dynamic recompilers work better than they would in emulation mode. diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index 18ae83dd1cd..b56c65de384 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c @@ -56,7 +56,7 @@ DEFINE_VVAR(struct vsyscall_gtod_data, vsyscall_gtod_data) = .lock = __SEQLOCK_UNLOCKED(__vsyscall_gtod_data.lock), }; -static enum { EMULATE, NATIVE, NONE } vsyscall_mode = EMULATE; +static enum { EMULATE, NATIVE, NONE } vsyscall_mode = NATIVE; static int __init vsyscall_setup(char *str) { -- cgit v1.2.3 From f7f43cc84152e53b5687cd0eb8823310ba065524 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Tue, 11 Oct 2011 11:41:40 -0400 Subject: Btrfs: make sure not to defrag extents past i_size The btrfs file defrag code will loop through the extents and force COW on them. But there is a concurrent truncate in the middle of the defrag, it might end up defragging the same range over and over again. The problem is that writepage won't go through and do anything on pages past i_size, so the cow won't happen, so the file will appear to still be fragmented. defrag will end up hitting the same extents again and again. In the worst case, the truncate can actually live lock with the defrag because the defrag keeps creating new ordered extents which the truncate code keeps waiting on. The fix here is to make defrag check for i_size inside the main loop, instead of just once before the looping starts. Signed-off-by: Chris Mason --- fs/btrfs/ioctl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index df40b7c5f06..efc4e4a85a6 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -1062,7 +1062,9 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, if (i < inode->i_mapping->writeback_index) inode->i_mapping->writeback_index = i; - while (i <= last_index && defrag_count < max_to_defrag) { + while (i <= last_index && defrag_count < max_to_defrag && + (i < (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> + PAGE_CACHE_SHIFT)) { /* * make sure we stop running if someone unmounts * the FS -- cgit v1.2.3 From bc6e588a8971aa74c02e42db4d6e0248679f3738 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 11 Oct 2011 15:14:08 +0000 Subject: xfs: do not update xa_last_pushed_lsn for locked items If an item was locked we should not update xa_last_pushed_lsn and thus skip it when restarting the AIL scan as we need to be able to lock and write it out as soon as possible. Otherwise heavy lock contention might starve AIL pushing too easily, especially given the larger backoff once we moved xa_last_pushed_lsn all the way to the target lsn. Signed-off-by: Christoph Hellwig Reported-by: Stefan Priebe Tested-by: Stefan Priebe Reviewed-by: Dave Chinner Signed-off-by: Alex Elder --- fs/xfs/xfs_trans_ail.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index c15aa29fa16..9bd1ee55ef6 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c @@ -440,7 +440,6 @@ xfs_ail_worker( case XFS_ITEM_LOCKED: XFS_STATS_INC(xs_push_ail_locked); - ailp->xa_last_pushed_lsn = lsn; stuck++; break; -- cgit v1.2.3 From 17b38471c3c07a49f0bbc2ecc2e92050c164e226 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 11 Oct 2011 15:14:09 +0000 Subject: xfs: force the log if we encounter pinned buffers in .iop_pushbuf We need to check for pinned buffers even in .iop_pushbuf given that inode items flush into the same buffers that may be pinned directly due operations on the unlinked inode list operating directly on buffers. To do this add a return value to .iop_pushbuf that tells the AIL push about this and use the existing log force mechanisms to unpin it. Signed-off-by: Christoph Hellwig Reported-by: Stefan Priebe Tested-by: Stefan Priebe Reviewed-by: Dave Chinner Signed-off-by: Alex Elder --- fs/xfs/xfs_buf_item.c | 3 ++- fs/xfs/xfs_dquot_item.c | 10 +++++++--- fs/xfs/xfs_inode_item.c | 10 +++++++--- fs/xfs/xfs_trans.h | 2 +- fs/xfs/xfs_trans_ail.c | 9 +++++++-- 5 files changed, 24 insertions(+), 10 deletions(-) diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index cac2ecfa674..ef43fce519a 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c @@ -629,7 +629,7 @@ xfs_buf_item_push( * the xfsbufd to get this buffer written. We have to unlock the buffer * to allow the xfsbufd to write it, too. */ -STATIC void +STATIC bool xfs_buf_item_pushbuf( struct xfs_log_item *lip) { @@ -643,6 +643,7 @@ xfs_buf_item_pushbuf( xfs_buf_delwri_promote(bp); xfs_buf_relse(bp); + return true; } STATIC void diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c index 9e0e2fa3f2c..bb3f71d236d 100644 --- a/fs/xfs/xfs_dquot_item.c +++ b/fs/xfs/xfs_dquot_item.c @@ -183,13 +183,14 @@ xfs_qm_dqunpin_wait( * search the buffer cache can be a time consuming thing, and AIL lock is a * spinlock. */ -STATIC void +STATIC bool xfs_qm_dquot_logitem_pushbuf( struct xfs_log_item *lip) { struct xfs_dq_logitem *qlip = DQUOT_ITEM(lip); struct xfs_dquot *dqp = qlip->qli_dquot; struct xfs_buf *bp; + bool ret = true; ASSERT(XFS_DQ_IS_LOCKED(dqp)); @@ -201,17 +202,20 @@ xfs_qm_dquot_logitem_pushbuf( if (completion_done(&dqp->q_flush) || !(lip->li_flags & XFS_LI_IN_AIL)) { xfs_dqunlock(dqp); - return; + return true; } bp = xfs_incore(dqp->q_mount->m_ddev_targp, qlip->qli_format.qlf_blkno, dqp->q_mount->m_quotainfo->qi_dqchunklen, XBF_TRYLOCK); xfs_dqunlock(dqp); if (!bp) - return; + return true; if (XFS_BUF_ISDELAYWRITE(bp)) xfs_buf_delwri_promote(bp); + if (xfs_buf_ispinned(bp)) + ret = false; xfs_buf_relse(bp); + return ret; } /* diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 588406dc6a3..836ad80d4f2 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -708,13 +708,14 @@ xfs_inode_item_committed( * marked delayed write. If that's the case, we'll promote it and that will * allow the caller to write the buffer by triggering the xfsbufd to run. */ -STATIC void +STATIC bool xfs_inode_item_pushbuf( struct xfs_log_item *lip) { struct xfs_inode_log_item *iip = INODE_ITEM(lip); struct xfs_inode *ip = iip->ili_inode; struct xfs_buf *bp; + bool ret = true; ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED)); @@ -725,7 +726,7 @@ xfs_inode_item_pushbuf( if (completion_done(&ip->i_flush) || !(lip->li_flags & XFS_LI_IN_AIL)) { xfs_iunlock(ip, XFS_ILOCK_SHARED); - return; + return true; } bp = xfs_incore(ip->i_mount->m_ddev_targp, iip->ili_format.ilf_blkno, @@ -733,10 +734,13 @@ xfs_inode_item_pushbuf( xfs_iunlock(ip, XFS_ILOCK_SHARED); if (!bp) - return; + return true; if (XFS_BUF_ISDELAYWRITE(bp)) xfs_buf_delwri_promote(bp); + if (xfs_buf_ispinned(bp)) + ret = false; xfs_buf_relse(bp); + return ret; } /* diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 06a9759b635..53597f4db9b 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -350,7 +350,7 @@ typedef struct xfs_item_ops { void (*iop_unlock)(xfs_log_item_t *); xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t); void (*iop_push)(xfs_log_item_t *); - void (*iop_pushbuf)(xfs_log_item_t *); + bool (*iop_pushbuf)(xfs_log_item_t *); void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t); } xfs_item_ops_t; diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 9bd1ee55ef6..e4cd9180d33 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c @@ -427,8 +427,13 @@ xfs_ail_worker( case XFS_ITEM_PUSHBUF: XFS_STATS_INC(xs_push_ail_pushbuf); - IOP_PUSHBUF(lip); - ailp->xa_last_pushed_lsn = lsn; + + if (!IOP_PUSHBUF(lip)) { + stuck++; + flush_log = 1; + } else { + ailp->xa_last_pushed_lsn = lsn; + } push_xfsbufd = 1; break; -- cgit v1.2.3 From 0030807c66f058230bcb20d2573bcaf28852e804 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 11 Oct 2011 11:14:10 -0400 Subject: xfs: revert to using a kthread for AIL pushing Currently we have a few issues with the way the workqueue code is used to implement AIL pushing: - it accidentally uses the same workqueue as the syncer action, and thus can be prevented from running if there are enough sync actions active in the system. - it doesn't use the HIGHPRI flag to queue at the head of the queue of work items At this point I'm not confident enough in getting all the workqueue flags and tweaks right to provide a perfectly reliable execution context for AIL pushing, which is the most important piece in XFS to make forward progress when the log fills. Revert back to use a kthread per filesystem which fixes all the above issues at the cost of having a task struct and stack around for each mounted filesystem. In addition this also gives us much better ways to diagnose any issues involving hung AIL pushing and removes a small amount of code. Signed-off-by: Christoph Hellwig Reported-by: Stefan Priebe Tested-by: Stefan Priebe Reviewed-by: Dave Chinner Signed-off-by: Alex Elder --- fs/xfs/xfs_linux.h | 2 ++ fs/xfs/xfs_super.c | 13 +-------- fs/xfs/xfs_trans_ail.c | 73 +++++++++++++++++++++++++++---------------------- fs/xfs/xfs_trans_priv.h | 8 +----- 4 files changed, 45 insertions(+), 51 deletions(-) diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h index 1e8a45e74c3..828662f70d6 100644 --- a/fs/xfs/xfs_linux.h +++ b/fs/xfs/xfs_linux.h @@ -68,6 +68,8 @@ #include #include #include +#include +#include #include #include diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 2366c54cc4f..5cf06b85fd9 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1652,24 +1652,13 @@ xfs_init_workqueues(void) */ xfs_syncd_wq = alloc_workqueue("xfssyncd", WQ_CPU_INTENSIVE, 8); if (!xfs_syncd_wq) - goto out; - - xfs_ail_wq = alloc_workqueue("xfsail", WQ_CPU_INTENSIVE, 8); - if (!xfs_ail_wq) - goto out_destroy_syncd; - + return -ENOMEM; return 0; - -out_destroy_syncd: - destroy_workqueue(xfs_syncd_wq); -out: - return -ENOMEM; } STATIC void xfs_destroy_workqueues(void) { - destroy_workqueue(xfs_ail_wq); destroy_workqueue(xfs_syncd_wq); } diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index e4cd9180d33..3a1e7ca54c2 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c @@ -28,8 +28,6 @@ #include "xfs_trans_priv.h" #include "xfs_error.h" -struct workqueue_struct *xfs_ail_wq; /* AIL workqueue */ - #ifdef DEBUG /* * Check that the list is sorted as it should be. @@ -356,16 +354,10 @@ xfs_ail_delete( xfs_trans_ail_cursor_clear(ailp, lip); } -/* - * xfs_ail_worker does the work of pushing on the AIL. It will requeue itself - * to run at a later time if there is more work to do to complete the push. - */ -STATIC void -xfs_ail_worker( - struct work_struct *work) +static long +xfsaild_push( + struct xfs_ail *ailp) { - struct xfs_ail *ailp = container_of(to_delayed_work(work), - struct xfs_ail, xa_work); xfs_mount_t *mp = ailp->xa_mount; struct xfs_ail_cursor cur; xfs_log_item_t *lip; @@ -505,20 +497,6 @@ out_done: /* We're past our target or empty, so idle */ ailp->xa_last_pushed_lsn = 0; - /* - * We clear the XFS_AIL_PUSHING_BIT first before checking - * whether the target has changed. If the target has changed, - * this pushes the requeue race directly onto the result of the - * atomic test/set bit, so we are guaranteed that either the - * the pusher that changed the target or ourselves will requeue - * the work (but not both). - */ - clear_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags); - smp_rmb(); - if (XFS_LSN_CMP(ailp->xa_target, target) == 0 || - test_and_set_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags)) - return; - tout = 50; } else if (XFS_LSN_CMP(lsn, target) >= 0) { /* @@ -541,9 +519,30 @@ out_done: tout = 20; } - /* There is more to do, requeue us. */ - queue_delayed_work(xfs_syncd_wq, &ailp->xa_work, - msecs_to_jiffies(tout)); + return tout; +} + +static int +xfsaild( + void *data) +{ + struct xfs_ail *ailp = data; + long tout = 0; /* milliseconds */ + + while (!kthread_should_stop()) { + if (tout && tout <= 20) + __set_current_state(TASK_KILLABLE); + else + __set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(tout ? + msecs_to_jiffies(tout) : MAX_SCHEDULE_TIMEOUT); + + try_to_freeze(); + + tout = xfsaild_push(ailp); + } + + return 0; } /* @@ -578,8 +577,9 @@ xfs_ail_push( */ smp_wmb(); xfs_trans_ail_copy_lsn(ailp, &ailp->xa_target, &threshold_lsn); - if (!test_and_set_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags)) - queue_delayed_work(xfs_syncd_wq, &ailp->xa_work, 0); + smp_wmb(); + + wake_up_process(ailp->xa_task); } /* @@ -817,9 +817,18 @@ xfs_trans_ail_init( INIT_LIST_HEAD(&ailp->xa_ail); INIT_LIST_HEAD(&ailp->xa_cursors); spin_lock_init(&ailp->xa_lock); - INIT_DELAYED_WORK(&ailp->xa_work, xfs_ail_worker); + + ailp->xa_task = kthread_run(xfsaild, ailp, "xfsaild/%s", + ailp->xa_mount->m_fsname); + if (IS_ERR(ailp->xa_task)) + goto out_free_ailp; + mp->m_ail = ailp; return 0; + +out_free_ailp: + kmem_free(ailp); + return ENOMEM; } void @@ -828,6 +837,6 @@ xfs_trans_ail_destroy( { struct xfs_ail *ailp = mp->m_ail; - cancel_delayed_work_sync(&ailp->xa_work); + kthread_stop(ailp->xa_task); kmem_free(ailp); } diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h index 212946b9723..22750b5e4a8 100644 --- a/fs/xfs/xfs_trans_priv.h +++ b/fs/xfs/xfs_trans_priv.h @@ -64,23 +64,17 @@ struct xfs_ail_cursor { */ struct xfs_ail { struct xfs_mount *xa_mount; + struct task_struct *xa_task; struct list_head xa_ail; xfs_lsn_t xa_target; struct list_head xa_cursors; spinlock_t xa_lock; - struct delayed_work xa_work; xfs_lsn_t xa_last_pushed_lsn; - unsigned long xa_flags; }; -#define XFS_AIL_PUSHING_BIT 0 - /* * From xfs_trans_ail.c */ - -extern struct workqueue_struct *xfs_ail_wq; /* AIL workqueue */ - void xfs_trans_ail_update_bulk(struct xfs_ail *ailp, struct xfs_ail_cursor *cur, struct xfs_log_item **log_items, int nr_items, -- cgit v1.2.3 From ae1d48b23d5e79efbcf0cef4f0ebb9742361af59 Mon Sep 17 00:00:00 2001 From: Hans Schillstrom Date: Tue, 11 Oct 2011 10:54:35 +0900 Subject: IPVS netns shutdown/startup dead-lock ip_vs_mutext is used by both netns shutdown code and startup and both implicit uses sk_lock-AF_INET mutex. cleanup CPU-1 startup CPU-2 ip_vs_dst_event() ip_vs_genl_set_cmd() sk_lock-AF_INET __ip_vs_mutex sk_lock-AF_INET __ip_vs_mutex * DEAD LOCK * A new mutex placed in ip_vs netns struct called sync_mutex is added. Comments from Julian and Simon added. This patch has been running for more than 3 month now and it seems to work. Ver. 3 IP_VS_SO_GET_DAEMON in do_ip_vs_get_ctl protected by sync_mutex instead of __ip_vs_mutex as sugested by Julian. Signed-off-by: Hans Schillstrom Acked-by: Julian Anastasov Signed-off-by: Simon Horman Signed-off-by: Pablo Neira Ayuso --- include/net/ip_vs.h | 1 + net/netfilter/ipvs/ip_vs_ctl.c | 131 ++++++++++++++++++++++++---------------- net/netfilter/ipvs/ip_vs_sync.c | 6 ++ 3 files changed, 87 insertions(+), 51 deletions(-) diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 1aaf915656f..8fa4430f99c 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -900,6 +900,7 @@ struct netns_ipvs { volatile int sync_state; volatile int master_syncid; volatile int backup_syncid; + struct mutex sync_mutex; /* multicast interface name */ char master_mcast_ifn[IP_VS_IFNAME_MAXLEN]; char backup_mcast_ifn[IP_VS_IFNAME_MAXLEN]; diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 2b771dc708a..3e5e08b78bf 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -2283,6 +2283,7 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) struct ip_vs_service *svc; struct ip_vs_dest_user *udest_compat; struct ip_vs_dest_user_kern udest; + struct netns_ipvs *ipvs = net_ipvs(net); if (!capable(CAP_NET_ADMIN)) return -EPERM; @@ -2303,6 +2304,24 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) /* increase the module use count */ ip_vs_use_count_inc(); + /* Handle daemons since they have another lock */ + if (cmd == IP_VS_SO_SET_STARTDAEMON || + cmd == IP_VS_SO_SET_STOPDAEMON) { + struct ip_vs_daemon_user *dm = (struct ip_vs_daemon_user *)arg; + + if (mutex_lock_interruptible(&ipvs->sync_mutex)) { + ret = -ERESTARTSYS; + goto out_dec; + } + if (cmd == IP_VS_SO_SET_STARTDAEMON) + ret = start_sync_thread(net, dm->state, dm->mcast_ifn, + dm->syncid); + else + ret = stop_sync_thread(net, dm->state); + mutex_unlock(&ipvs->sync_mutex); + goto out_dec; + } + if (mutex_lock_interruptible(&__ip_vs_mutex)) { ret = -ERESTARTSYS; goto out_dec; @@ -2316,15 +2335,6 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) /* Set timeout values for (tcp tcpfin udp) */ ret = ip_vs_set_timeout(net, (struct ip_vs_timeout_user *)arg); goto out_unlock; - } else if (cmd == IP_VS_SO_SET_STARTDAEMON) { - struct ip_vs_daemon_user *dm = (struct ip_vs_daemon_user *)arg; - ret = start_sync_thread(net, dm->state, dm->mcast_ifn, - dm->syncid); - goto out_unlock; - } else if (cmd == IP_VS_SO_SET_STOPDAEMON) { - struct ip_vs_daemon_user *dm = (struct ip_vs_daemon_user *)arg; - ret = stop_sync_thread(net, dm->state); - goto out_unlock; } usvc_compat = (struct ip_vs_service_user *)arg; @@ -2584,6 +2594,33 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) if (copy_from_user(arg, user, copylen) != 0) return -EFAULT; + /* + * Handle daemons first since it has its own locking + */ + if (cmd == IP_VS_SO_GET_DAEMON) { + struct ip_vs_daemon_user d[2]; + + memset(&d, 0, sizeof(d)); + if (mutex_lock_interruptible(&ipvs->sync_mutex)) + return -ERESTARTSYS; + + if (ipvs->sync_state & IP_VS_STATE_MASTER) { + d[0].state = IP_VS_STATE_MASTER; + strlcpy(d[0].mcast_ifn, ipvs->master_mcast_ifn, + sizeof(d[0].mcast_ifn)); + d[0].syncid = ipvs->master_syncid; + } + if (ipvs->sync_state & IP_VS_STATE_BACKUP) { + d[1].state = IP_VS_STATE_BACKUP; + strlcpy(d[1].mcast_ifn, ipvs->backup_mcast_ifn, + sizeof(d[1].mcast_ifn)); + d[1].syncid = ipvs->backup_syncid; + } + if (copy_to_user(user, &d, sizeof(d)) != 0) + ret = -EFAULT; + mutex_unlock(&ipvs->sync_mutex); + return ret; + } if (mutex_lock_interruptible(&__ip_vs_mutex)) return -ERESTARTSYS; @@ -2681,28 +2718,6 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) } break; - case IP_VS_SO_GET_DAEMON: - { - struct ip_vs_daemon_user d[2]; - - memset(&d, 0, sizeof(d)); - if (ipvs->sync_state & IP_VS_STATE_MASTER) { - d[0].state = IP_VS_STATE_MASTER; - strlcpy(d[0].mcast_ifn, ipvs->master_mcast_ifn, - sizeof(d[0].mcast_ifn)); - d[0].syncid = ipvs->master_syncid; - } - if (ipvs->sync_state & IP_VS_STATE_BACKUP) { - d[1].state = IP_VS_STATE_BACKUP; - strlcpy(d[1].mcast_ifn, ipvs->backup_mcast_ifn, - sizeof(d[1].mcast_ifn)); - d[1].syncid = ipvs->backup_syncid; - } - if (copy_to_user(user, &d, sizeof(d)) != 0) - ret = -EFAULT; - } - break; - default: ret = -EINVAL; } @@ -3205,7 +3220,7 @@ static int ip_vs_genl_dump_daemons(struct sk_buff *skb, struct net *net = skb_sknet(skb); struct netns_ipvs *ipvs = net_ipvs(net); - mutex_lock(&__ip_vs_mutex); + mutex_lock(&ipvs->sync_mutex); if ((ipvs->sync_state & IP_VS_STATE_MASTER) && !cb->args[0]) { if (ip_vs_genl_dump_daemon(skb, IP_VS_STATE_MASTER, ipvs->master_mcast_ifn, @@ -3225,7 +3240,7 @@ static int ip_vs_genl_dump_daemons(struct sk_buff *skb, } nla_put_failure: - mutex_unlock(&__ip_vs_mutex); + mutex_unlock(&ipvs->sync_mutex); return skb->len; } @@ -3271,13 +3286,9 @@ static int ip_vs_genl_set_config(struct net *net, struct nlattr **attrs) return ip_vs_set_timeout(net, &t); } -static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info) +static int ip_vs_genl_set_daemon(struct sk_buff *skb, struct genl_info *info) { - struct ip_vs_service *svc = NULL; - struct ip_vs_service_user_kern usvc; - struct ip_vs_dest_user_kern udest; int ret = 0, cmd; - int need_full_svc = 0, need_full_dest = 0; struct net *net; struct netns_ipvs *ipvs; @@ -3285,19 +3296,10 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info) ipvs = net_ipvs(net); cmd = info->genlhdr->cmd; - mutex_lock(&__ip_vs_mutex); - - if (cmd == IPVS_CMD_FLUSH) { - ret = ip_vs_flush(net); - goto out; - } else if (cmd == IPVS_CMD_SET_CONFIG) { - ret = ip_vs_genl_set_config(net, info->attrs); - goto out; - } else if (cmd == IPVS_CMD_NEW_DAEMON || - cmd == IPVS_CMD_DEL_DAEMON) { - + if (cmd == IPVS_CMD_NEW_DAEMON || cmd == IPVS_CMD_DEL_DAEMON) { struct nlattr *daemon_attrs[IPVS_DAEMON_ATTR_MAX + 1]; + mutex_lock(&ipvs->sync_mutex); if (!info->attrs[IPVS_CMD_ATTR_DAEMON] || nla_parse_nested(daemon_attrs, IPVS_DAEMON_ATTR_MAX, info->attrs[IPVS_CMD_ATTR_DAEMON], @@ -3310,6 +3312,33 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info) ret = ip_vs_genl_new_daemon(net, daemon_attrs); else ret = ip_vs_genl_del_daemon(net, daemon_attrs); +out: + mutex_unlock(&ipvs->sync_mutex); + } + return ret; +} + +static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info) +{ + struct ip_vs_service *svc = NULL; + struct ip_vs_service_user_kern usvc; + struct ip_vs_dest_user_kern udest; + int ret = 0, cmd; + int need_full_svc = 0, need_full_dest = 0; + struct net *net; + struct netns_ipvs *ipvs; + + net = skb_sknet(skb); + ipvs = net_ipvs(net); + cmd = info->genlhdr->cmd; + + mutex_lock(&__ip_vs_mutex); + + if (cmd == IPVS_CMD_FLUSH) { + ret = ip_vs_flush(net); + goto out; + } else if (cmd == IPVS_CMD_SET_CONFIG) { + ret = ip_vs_genl_set_config(net, info->attrs); goto out; } else if (cmd == IPVS_CMD_ZERO && !info->attrs[IPVS_CMD_ATTR_SERVICE]) { @@ -3536,13 +3565,13 @@ static struct genl_ops ip_vs_genl_ops[] __read_mostly = { .cmd = IPVS_CMD_NEW_DAEMON, .flags = GENL_ADMIN_PERM, .policy = ip_vs_cmd_policy, - .doit = ip_vs_genl_set_cmd, + .doit = ip_vs_genl_set_daemon, }, { .cmd = IPVS_CMD_DEL_DAEMON, .flags = GENL_ADMIN_PERM, .policy = ip_vs_cmd_policy, - .doit = ip_vs_genl_set_cmd, + .doit = ip_vs_genl_set_daemon, }, { .cmd = IPVS_CMD_GET_DAEMON, diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c index 7ee7215b8ba..3cdd479f9b5 100644 --- a/net/netfilter/ipvs/ip_vs_sync.c +++ b/net/netfilter/ipvs/ip_vs_sync.c @@ -61,6 +61,7 @@ #define SYNC_PROTO_VER 1 /* Protocol version in header */ +static struct lock_class_key __ipvs_sync_key; /* * IPVS sync connection entry * Version 0, i.e. original version. @@ -1545,6 +1546,7 @@ int start_sync_thread(struct net *net, int state, char *mcast_ifn, __u8 syncid) IP_VS_DBG(7, "Each ip_vs_sync_conn entry needs %Zd bytes\n", sizeof(struct ip_vs_sync_conn_v0)); + if (state == IP_VS_STATE_MASTER) { if (ipvs->master_thread) return -EEXIST; @@ -1667,6 +1669,7 @@ int __net_init ip_vs_sync_net_init(struct net *net) { struct netns_ipvs *ipvs = net_ipvs(net); + __mutex_init(&ipvs->sync_mutex, "ipvs->sync_mutex", &__ipvs_sync_key); INIT_LIST_HEAD(&ipvs->sync_queue); spin_lock_init(&ipvs->sync_lock); spin_lock_init(&ipvs->sync_buff_lock); @@ -1680,7 +1683,9 @@ int __net_init ip_vs_sync_net_init(struct net *net) void ip_vs_sync_net_cleanup(struct net *net) { int retc; + struct netns_ipvs *ipvs = net_ipvs(net); + mutex_lock(&ipvs->sync_mutex); retc = stop_sync_thread(net, IP_VS_STATE_MASTER); if (retc && retc != -ESRCH) pr_err("Failed to stop Master Daemon\n"); @@ -1688,4 +1693,5 @@ void ip_vs_sync_net_cleanup(struct net *net) retc = stop_sync_thread(net, IP_VS_STATE_BACKUP); if (retc && retc != -ESRCH) pr_err("Failed to stop Backup Daemon\n"); + mutex_unlock(&ipvs->sync_mutex); } -- cgit v1.2.3 From faddf598f0ba98ba329bb83acad51aea40313c2a Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 11 Aug 2011 14:57:02 +0100 Subject: sparc: Use set_current_blocked() As described in e6fa16ab ("signal: sigprocmask() should do retarget_shared_pending()") the modification of current->blocked is incorrect as we need to check whether the signal we're about to block is pending in the shared queue. Cc: Oleg Nesterov Cc: "David S. Miller" Signed-off-by: Matt Fleming Signed-off-by: David S. Miller --- arch/sparc/kernel/signal32.c | 19 ++++++------------- arch/sparc/kernel/signal_32.c | 30 ++++++++++++------------------ arch/sparc/kernel/signal_64.c | 30 ++++++++++++------------------ 3 files changed, 30 insertions(+), 49 deletions(-) diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index 1ba95aff5d5..3b3a3fc3ce0 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c @@ -273,10 +273,7 @@ void do_sigreturn32(struct pt_regs *regs) case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32); } sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + set_current_blocked(&set); return; segv: @@ -377,10 +374,7 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) case 1: set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32); } sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + set_current_blocked(&set); return; segv: force_sig(SIGSEGV, current); @@ -782,6 +776,7 @@ static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) { + sigset_t blocked; int err; if (ka->sa.sa_flags & SA_SIGINFO) @@ -792,12 +787,10 @@ static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka, if (err) return err; - spin_lock_irq(¤t->sighand->siglock); - sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); + sigorsets(&blocked, ¤t->blocked, &ka->sa.sa_mask); if (!(ka->sa.sa_flags & SA_NOMASK)) - sigaddset(¤t->blocked,signr); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + sigaddset(&blocked, signr); + set_current_blocked(&blocked); tracehook_signal_handler(signr, info, ka, regs, 0); diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c index 04ede8f04ad..030087a63fb 100644 --- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c @@ -62,12 +62,13 @@ struct rt_signal_frame { static int _sigpause_common(old_sigset_t set) { - set &= _BLOCKABLE; - spin_lock_irq(¤t->sighand->siglock); + sigset_t blocked; + current->saved_sigmask = current->blocked; - siginitset(¤t->blocked, set); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + + set &= _BLOCKABLE; + siginitset(&blocked, set); + set_current_blocked(&blocked); current->state = TASK_INTERRUPTIBLE; schedule(); @@ -139,10 +140,7 @@ asmlinkage void do_sigreturn(struct pt_regs *regs) goto segv_and_exit; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + set_current_blocked(&set); return; segv_and_exit: @@ -209,10 +207,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) } sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + set_current_blocked(&set); return; segv: force_sig(SIGSEGV, current); @@ -470,6 +465,7 @@ static inline int handle_signal(unsigned long signr, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) { + sigset_t blocked; int err; if (ka->sa.sa_flags & SA_SIGINFO) @@ -480,12 +476,10 @@ handle_signal(unsigned long signr, struct k_sigaction *ka, if (err) return err; - spin_lock_irq(¤t->sighand->siglock); - sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); + sigorsets(&blocked, ¤t->blocked, &ka->sa.sa_mask); if (!(ka->sa.sa_flags & SA_NOMASK)) - sigaddset(¤t->blocked, signr); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + sigaddset(&blocked, signr); + set_current_blocked(&blocked); tracehook_signal_handler(signr, info, ka, regs, 0); diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 47509df3b89..f895c407648 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c @@ -70,10 +70,7 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs) goto do_sigsegv; } sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + set_current_blocked(&set); } if (test_thread_flag(TIF_32BIT)) { pc &= 0xffffffff; @@ -242,12 +239,13 @@ struct rt_signal_frame { static long _sigpause_common(old_sigset_t set) { - set &= _BLOCKABLE; - spin_lock_irq(¤t->sighand->siglock); + sigset_t blocked; + current->saved_sigmask = current->blocked; - siginitset(¤t->blocked, set); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + + set &= _BLOCKABLE; + siginitset(&blocked, set); + set_current_blocked(&blocked); current->state = TASK_INTERRUPTIBLE; schedule(); @@ -327,10 +325,7 @@ void do_rt_sigreturn(struct pt_regs *regs) pt_regs_clear_syscall(regs); sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + set_current_blocked(&set); return; segv: force_sig(SIGSEGV, current); @@ -484,18 +479,17 @@ static inline int handle_signal(unsigned long signr, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) { + sigset_t blocked; int err; err = setup_rt_frame(ka, regs, signr, oldset, (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); if (err) return err; - spin_lock_irq(¤t->sighand->siglock); - sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); + sigorsets(&blocked, ¤t->blocked, &ka->sa.sa_mask); if (!(ka->sa.sa_flags & SA_NOMASK)) - sigaddset(¤t->blocked,signr); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + sigaddset(&blocked, signr); + set_current_blocked(&blocked); tracehook_signal_handler(signr, info, ka, regs, 0); -- cgit v1.2.3 From 27f20dca01b00eac445e5193565dd185548e7e34 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 12 Oct 2011 12:27:35 -0700 Subject: sparc: Avoid calling sigprocmask() Use set_current_blocked() instead. Signed-off-by: David S. Miller --- arch/sparc/kernel/signal32.c | 2 +- arch/sparc/kernel/signal_32.c | 2 +- arch/sparc/kernel/signal_64.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index 3b3a3fc3ce0..2caa556db86 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c @@ -874,7 +874,7 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, */ if (current_thread_info()->status & TS_RESTORE_SIGMASK) { current_thread_info()->status &= ~TS_RESTORE_SIGMASK; - sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); + set_current_blocked(¤t->saved_sigmask); } } diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c index 030087a63fb..8ce247ac04c 100644 --- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c @@ -575,7 +575,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) { clear_thread_flag(TIF_RESTORE_SIGMASK); - sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); + set_current_blocked(¤t->saved_sigmask); } } diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index f895c407648..a2b81598d90 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c @@ -595,7 +595,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) */ if (current_thread_info()->status & TS_RESTORE_SIGMASK) { current_thread_info()->status &= ~TS_RESTORE_SIGMASK; - sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); + set_current_blocked(¤t->saved_sigmask); } } -- cgit v1.2.3 From 1d1136012163ab5e33a97f9779af269cf4049cb9 Mon Sep 17 00:00:00 2001 From: Johann Felix Soden Date: Mon, 10 Oct 2011 11:37:00 -0700 Subject: ide: Fix file references in drivers/ide/ Fix file references in drivers/ide/ There are a lot of file references to now moved or deleted files in the whole tree, especially in documentation and Kconfig files. This patch fixes the references in drivers/ide/. Signed-off-by: Johann Felix Soden Signed-off-by: Randy Dunlap Acked-by: David S. Miller Signed-off-by: Linus Torvalds --- drivers/ide/Kconfig | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 9827c5e686c..811dbbd9306 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -327,7 +327,7 @@ config BLK_DEV_OPTI621 select BLK_DEV_IDEPCI help This is a driver for the OPTi 82C621 EIDE controller. - Please read the comments at the top of . + Please read the comments at the top of . config BLK_DEV_RZ1000 tristate "RZ1000 chipset bugfix/support" @@ -365,7 +365,7 @@ config BLK_DEV_ALI15X3 normal dual channel support. Please read the comments at the top of - . + . If unsure, say N. @@ -528,7 +528,7 @@ config BLK_DEV_NS87415 This driver adds detection and support for the NS87415 chip (used mainly on SPARC64 and PA-RISC machines). - Please read the comments at the top of . + Please read the comments at the top of . config BLK_DEV_PDC202XX_OLD tristate "PROMISE PDC202{46|62|65|67} support" @@ -547,7 +547,7 @@ config BLK_DEV_PDC202XX_OLD for more than one card. Please read the comments at the top of - . + . If unsure, say N. @@ -593,7 +593,7 @@ config BLK_DEV_SIS5513 ATA100: SiS635, SiS645, SiS650, SiS730, SiS735, SiS740, SiS745, SiS750 - Please read the comments at the top of . + Please read the comments at the top of . config BLK_DEV_SL82C105 tristate "Winbond SL82c105 support" @@ -616,7 +616,7 @@ config BLK_DEV_SLC90E66 look-a-like to the PIIX4 it should be a nice addition. Please read the comments at the top of - . + . config BLK_DEV_TRM290 tristate "Tekram TRM290 chipset support" @@ -625,7 +625,7 @@ config BLK_DEV_TRM290 This driver adds support for bus master DMA transfers using the Tekram TRM290 PCI IDE chip. Volunteers are needed for further tweaking and development. - Please read the comments at the top of . + Please read the comments at the top of . config BLK_DEV_VIA82CXXX tristate "VIA82CXXX chipset support" @@ -836,7 +836,7 @@ config BLK_DEV_ALI14XX of the ALI M1439/1443/1445/1487/1489 chipsets, and permits faster I/O speeds to be set as well. See the files and - for more info. + for more info. config BLK_DEV_DTC2278 tristate "DTC-2278 support" @@ -847,7 +847,7 @@ config BLK_DEV_DTC2278 boot parameter. It enables support for the secondary IDE interface of the DTC-2278 card, and permits faster I/O speeds to be set as well. See the and - files for more info. + files for more info. config BLK_DEV_HT6560B tristate "Holtek HT6560B support" @@ -858,7 +858,7 @@ config BLK_DEV_HT6560B boot parameter. It enables support for the secondary IDE interface of the Holtek card, and permits faster I/O speeds to be set as well. See the and - files for more info. + files for more info. config BLK_DEV_QD65XX tristate "QDI QD65xx support" @@ -867,7 +867,7 @@ config BLK_DEV_QD65XX help This driver is enabled at runtime using the "qd65xx.probe" kernel boot parameter. It permits faster I/O speeds to be set. See the - and + and for more info. config BLK_DEV_UMC8672 @@ -879,7 +879,7 @@ config BLK_DEV_UMC8672 boot parameter. It enables support for the secondary IDE interface of the UMC-8672, and permits faster I/O speeds to be set as well. See the files and - for more info. + for more info. endif -- cgit v1.2.3 From d52104b29a3735f2b4dceefcb01b19d370a783ea Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Wed, 5 Oct 2011 17:09:29 -0400 Subject: tile: revert change from to in asm files The 32-bit TILEPro support uses some #defines in for atomic support routines in assembly. To make this more explicit, I've turned those includes into includes of , which should hopefully make it clear that they shouldn't be bombed into in any cleanups. Signed-off-by: Chris Metcalf --- arch/tile/kernel/intvec_32.S | 2 +- arch/tile/lib/atomic_asm_32.S | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S index fc94607f0bd..aecc8ed5f39 100644 --- a/arch/tile/kernel/intvec_32.S +++ b/arch/tile/kernel/intvec_32.S @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/tile/lib/atomic_asm_32.S b/arch/tile/lib/atomic_asm_32.S index 1f75a2a5610..30638042691 100644 --- a/arch/tile/lib/atomic_asm_32.S +++ b/arch/tile/lib/atomic_asm_32.S @@ -70,7 +70,7 @@ */ #include -#include +#include #include #include -- cgit v1.2.3 From 78a43158724793f9dc25f1e4c866393654704b87 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Tue, 23 Aug 2011 13:42:24 +0200 Subject: gpio/omap: fix build error with certain OMAP1 configs With commit f64ad1a0e21a, "gpio/omap: cleanup _set_gpio_wakeup(), remove ifdefs", access to build time conditionally omitted 'suspend_wakeup' member of the 'gpio_bank' structure has been placed unconditionally in function _set_gpio_wakeup(), which is always built. This resulted in the driver compilation broken for certain OMAP1, i.e., non-OMAP16xx, configurations. Really required or not in previously excluded cases, define this structure member unconditionally as a fix. Tested with a custom OMAP1510 only configuration. Signed-off-by: Janusz Krzysztofik Acked-by: Kevin Hilman Tested-by: Aaro Koskinen Signed-off-by: Grant Likely --- drivers/gpio/gpio-omap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 0599854e221..118ec12d2d5 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -34,8 +34,8 @@ struct gpio_bank { u16 irq; u16 virtual_irq_start; int method; -#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS) u32 suspend_wakeup; +#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS) u32 saved_wakeup; #endif u32 non_wakeup_gpios; -- cgit v1.2.3 From 25fcf2b7f1f65d2cc12182ced3ccd47576970be4 Mon Sep 17 00:00:00 2001 From: Hartmut Knaack Date: Tue, 11 Oct 2011 00:22:45 +0200 Subject: gpio-pca953x: fix gpio_base gpio_base was set to 0 if no system platform data or open firmware platform data was provided. This led to conflicts, if any other gpiochip with a gpiobase of 0 was instantiated already. Setting it to -1 will automatically use the first one available. Signed-off-by: Hartmut Knaack Signed-off-by: Grant Likely --- drivers/gpio/gpio-pca953x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index c43b8ff626a..0550dcb8581 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -577,6 +577,7 @@ pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) void pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) { + *gpio_base = -1; } #endif -- cgit v1.2.3 From bf164c58e58328c40ebc597a8ac00cc6840f9703 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 13 Oct 2011 15:49:08 -0400 Subject: hwmon: (w83627ehf) Properly report thermal diode sensors The w83627ehf driver is improperly reporting thermal diode sensors as type 2, instead of 3. This caused "sensors" and possibly other monitoring tools to report these sensors as "transistor" instead of "thermal diode". Furthermore, diode subtype selection (CPU vs. external) is only supported by the original W83627EHF/EHG. All later models only support CPU diode type, and some (NCT6776F) don't even have the register in question so we should avoid reading from it. Signed-off-by: Jean Delvare Cc: stable@kernel.org Signed-off-by: Guenter Roeck --- drivers/hwmon/w83627ehf.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index f2b377c56a3..7b0260dc76f 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c @@ -1715,7 +1715,8 @@ static void w83627ehf_device_remove_files(struct device *dev) } /* Get the monitoring functions started */ -static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data) +static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data, + enum kinds kind) { int i; u8 tmp, diode; @@ -1746,10 +1747,16 @@ static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data) w83627ehf_write_value(data, W83627EHF_REG_VBAT, tmp | 0x01); /* Get thermal sensor types */ - diode = w83627ehf_read_value(data, W83627EHF_REG_DIODE); + switch (kind) { + case w83627ehf: + diode = w83627ehf_read_value(data, W83627EHF_REG_DIODE); + break; + default: + diode = 0x70; + } for (i = 0; i < 3; i++) { if ((tmp & (0x02 << i))) - data->temp_type[i] = (diode & (0x10 << i)) ? 1 : 2; + data->temp_type[i] = (diode & (0x10 << i)) ? 1 : 3; else data->temp_type[i] = 4; /* thermistor */ } @@ -2016,7 +2023,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) } /* Initialize the chip */ - w83627ehf_init_device(data); + w83627ehf_init_device(data, sio_data->kind); data->vrm = vid_which_vrm(); superio_enter(sio_data->sioreg); -- cgit v1.2.3 From 153b19a3b9fd8b9478495b9ee1f93f6a77c564f9 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 13 Oct 2011 12:04:20 +0300 Subject: x86, mrst: use a temporary variable for SFI irq SFI tables reside in RAM and should not be modified once they are written. Current code went to set pentry->irq to zero which causes subsequent reads to fail with invalid SFI table checksum. This will break kexec as the second kernel fails to validate SFI tables. To fix this we use temporary variable for irq number. Signed-off-by: Mika Westerberg Reviewed-by: Kirill A. Shutemov Cc: stable@kernel.org Signed-off-by: Linus Torvalds --- arch/x86/platform/mrst/mrst.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/arch/x86/platform/mrst/mrst.c b/arch/x86/platform/mrst/mrst.c index 58425adc22c..fe73276e026 100644 --- a/arch/x86/platform/mrst/mrst.c +++ b/arch/x86/platform/mrst/mrst.c @@ -678,38 +678,40 @@ static int __init sfi_parse_devs(struct sfi_table_header *table) pentry = (struct sfi_device_table_entry *)sb->pentry; for (i = 0; i < num; i++, pentry++) { - if (pentry->irq != (u8)0xff) { /* native RTE case */ + int irq = pentry->irq; + + if (irq != (u8)0xff) { /* native RTE case */ /* these SPI2 devices are not exposed to system as PCI * devices, but they have separate RTE entry in IOAPIC * so we have to enable them one by one here */ - ioapic = mp_find_ioapic(pentry->irq); + ioapic = mp_find_ioapic(irq); irq_attr.ioapic = ioapic; - irq_attr.ioapic_pin = pentry->irq; + irq_attr.ioapic_pin = irq; irq_attr.trigger = 1; irq_attr.polarity = 1; - io_apic_set_pci_routing(NULL, pentry->irq, &irq_attr); + io_apic_set_pci_routing(NULL, irq, &irq_attr); } else - pentry->irq = 0; /* No irq */ + irq = 0; /* No irq */ switch (pentry->type) { case SFI_DEV_TYPE_IPC: /* ID as IRQ is a hack that will go away */ - pdev = platform_device_alloc(pentry->name, pentry->irq); + pdev = platform_device_alloc(pentry->name, irq); if (pdev == NULL) { pr_err("out of memory for SFI platform device '%s'.\n", pentry->name); continue; } - install_irq_resource(pdev, pentry->irq); + install_irq_resource(pdev, irq); pr_debug("info[%2d]: IPC bus, name = %16.16s, " - "irq = 0x%2x\n", i, pentry->name, pentry->irq); + "irq = 0x%2x\n", i, pentry->name, irq); sfi_handle_ipc_dev(pdev); break; case SFI_DEV_TYPE_SPI: memset(&spi_info, 0, sizeof(spi_info)); strncpy(spi_info.modalias, pentry->name, SFI_NAME_LEN); - spi_info.irq = pentry->irq; + spi_info.irq = irq; spi_info.bus_num = pentry->host_num; spi_info.chip_select = pentry->addr; spi_info.max_speed_hz = pentry->max_freq; @@ -726,7 +728,7 @@ static int __init sfi_parse_devs(struct sfi_table_header *table) memset(&i2c_info, 0, sizeof(i2c_info)); bus = pentry->host_num; strncpy(i2c_info.type, pentry->name, SFI_NAME_LEN); - i2c_info.irq = pentry->irq; + i2c_info.irq = irq; i2c_info.addr = pentry->addr; pr_debug("info[%2d]: I2C bus = %d, name = %16.16s, " "irq = 0x%2x, addr = 0x%x\n", i, bus, -- cgit v1.2.3 From 29a541f6c1f6e4a85628bb86071b9e72c9f8be2c Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Mon, 3 Oct 2011 18:30:53 +0100 Subject: ARM: 7117/1: perf: fix HW_CACHE_* events on Cortex-A9 Using COHERENT_LINE_{MISS,HIT} for cache misses and references respectively is completely wrong. Instead, use the L1D events which are a better and more useful approximation despite ignoring instruction traffic. Reported-by: Alasdair Grant Reported-by: Matt Horsnell Reported-by: Michael Williams Cc: stable@kernel.org Cc: Jean Pihet Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/kernel/perf_event_v7.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c index 4c851834f68..6be3e2e4d83 100644 --- a/arch/arm/kernel/perf_event_v7.c +++ b/arch/arm/kernel/perf_event_v7.c @@ -321,8 +321,8 @@ static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = { [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES, [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE, - [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_COHERENT_LINE_HIT, - [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_COHERENT_LINE_MISS, + [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_DCACHE_ACCESS, + [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_DCACHE_REFILL, [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE, [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES, -- cgit v1.2.3 From bb1ac3ec95cf0cce5145617b140f2090ed45d565 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 6 Oct 2011 14:57:24 +0100 Subject: ARM: 7122/1: localtimer: add header linux/errno.h explicitly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per the text in Documentation/SubmitChecklist as below, we should explicitly have header linux/errno.h in localtimer.h for ENXIO reference. 1: If you use a facility then #include the file that defines/declares that facility. Don't depend on other header files pulling in ones that you use. Otherwise, we may run into some compiling error like the following one, if any file includes localtimer.h without CONFIG_LOCAL_TIMERS defined. arch/arm/include/asm/localtimer.h: In function ‘local_timer_setup’: arch/arm/include/asm/localtimer.h:53:10: error: ‘ENXIO’ undeclared (first use in this function) Signed-off-by: Shawn Guo Signed-off-by: Russell King --- arch/arm/include/asm/localtimer.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h index 080d74f8128..ff66638ff54 100644 --- a/arch/arm/include/asm/localtimer.h +++ b/arch/arm/include/asm/localtimer.h @@ -10,6 +10,8 @@ #ifndef __ASM_ARM_LOCALTIMER_H #define __ASM_ARM_LOCALTIMER_H +#include + struct clock_event_device; /* -- cgit v1.2.3 From f8be12d15374413cf437741a282e97129e759209 Mon Sep 17 00:00:00 2001 From: Zoltan Devai Date: Mon, 10 Oct 2011 14:54:12 +0100 Subject: ARM: 7128/1: vic: Don't write to the read-only register VIC_IRQ_STATUS This is unneeded and causes an abort on the SPMP8000 platform. Acked-by: Linus Walleij Signed-off-by: Zoltan Devai Signed-off-by: Russell King --- arch/arm/common/vic.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c index 7aa4262ada7..197f81c7735 100644 --- a/arch/arm/common/vic.c +++ b/arch/arm/common/vic.c @@ -259,7 +259,6 @@ static void __init vic_disable(void __iomem *base) writel(0, base + VIC_INT_SELECT); writel(0, base + VIC_INT_ENABLE); writel(~0, base + VIC_INT_ENABLE_CLEAR); - writel(0, base + VIC_IRQ_STATUS); writel(0, base + VIC_ITCR); writel(~0, base + VIC_INT_SOFT_CLEAR); } -- cgit v1.2.3 From a84a79e4d369a73c0130b5858199e949432da4c6 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 17 Oct 2011 08:24:24 -0700 Subject: Avoid using variable-length arrays in kernel/sys.c The size is always valid, but variable-length arrays generate worse code for no good reason (unless the function happens to be inlined and the compiler sees the length for the simple constant it is). Also, there seems to be some code generation problem on POWER, where Henrik Bakken reports that register r28 can get corrupted under some subtle circumstances (interrupt happening at the wrong time?). That all indicates some seriously broken compiler issues, but since variable length arrays are bad regardless, there's little point in trying to chase it down. "Just don't do that, then". Reported-by: Henrik Grindal Bakken Cc: Benjamin Herrenschmidt Cc: stable@kernel.org Signed-off-by: Linus Torvalds --- kernel/sys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sys.c b/kernel/sys.c index 18ee1d2f647..1dbbe695a5e 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -1172,7 +1172,7 @@ DECLARE_RWSEM(uts_sem); static int override_release(char __user *release, int len) { int ret = 0; - char buf[len]; + char buf[65]; if (current->personality & UNAME26) { char *rest = UTS_RELEASE; -- cgit v1.2.3 From f36c23bb9f822904dacf83a329518d0a5fde7968 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Mon, 17 Oct 2011 19:07:30 -0400 Subject: udplite: fast-path computation of checksum coverage Commit 903ab86d195cca295379699299c5fc10beba31c7 of 1 March this year ("udp: Add lockless transmit path") introduced a new fast TX path that broke the checksum coverage computation of UDP-lite, which so far depended on up->len (only set if the socket is locked and 0 in the fast path). Fixed by providing both fast- and slow-path computation of checksum coverage. The latter can be removed when UDP(-lite)v6 also uses a lockless transmit path. Reported-by: Thomas Volkert Signed-off-by: Gerrit Renker Signed-off-by: David S. Miller --- include/net/udplite.h | 63 +++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/include/net/udplite.h b/include/net/udplite.h index 673a024c6b2..5f097ca7d5c 100644 --- a/include/net/udplite.h +++ b/include/net/udplite.h @@ -66,40 +66,34 @@ static inline int udplite_checksum_init(struct sk_buff *skb, struct udphdr *uh) return 0; } -static inline int udplite_sender_cscov(struct udp_sock *up, struct udphdr *uh) +/* Slow-path computation of checksum. Socket is locked. */ +static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb) { + const struct udp_sock *up = udp_sk(skb->sk); int cscov = up->len; + __wsum csum = 0; - /* - * Sender has set `partial coverage' option on UDP-Lite socket - */ - if (up->pcflag & UDPLITE_SEND_CC) { + if (up->pcflag & UDPLITE_SEND_CC) { + /* + * Sender has set `partial coverage' option on UDP-Lite socket. + * The special case "up->pcslen == 0" signifies full coverage. + */ if (up->pcslen < up->len) { - /* up->pcslen == 0 means that full coverage is required, - * partial coverage only if 0 < up->pcslen < up->len */ - if (0 < up->pcslen) { - cscov = up->pcslen; - } - uh->len = htons(up->pcslen); + if (0 < up->pcslen) + cscov = up->pcslen; + udp_hdr(skb)->len = htons(up->pcslen); } - /* - * NOTE: Causes for the error case `up->pcslen > up->len': - * (i) Application error (will not be penalized). - * (ii) Payload too big for send buffer: data is split - * into several packets, each with its own header. - * In this case (e.g. last segment), coverage may - * exceed packet length. - * Since packets with coverage length > packet length are - * illegal, we fall back to the defaults here. - */ + /* + * NOTE: Causes for the error case `up->pcslen > up->len': + * (i) Application error (will not be penalized). + * (ii) Payload too big for send buffer: data is split + * into several packets, each with its own header. + * In this case (e.g. last segment), coverage may + * exceed packet length. + * Since packets with coverage length > packet length are + * illegal, we fall back to the defaults here. + */ } - return cscov; -} - -static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb) -{ - int cscov = udplite_sender_cscov(udp_sk(sk), udp_hdr(skb)); - __wsum csum = 0; skb->ip_summed = CHECKSUM_NONE; /* no HW support for checksumming */ @@ -115,16 +109,21 @@ static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb) return csum; } +/* Fast-path computation of checksum. Socket may not be locked. */ static inline __wsum udplite_csum(struct sk_buff *skb) { - struct sock *sk = skb->sk; - int cscov = udplite_sender_cscov(udp_sk(sk), udp_hdr(skb)); + const struct udp_sock *up = udp_sk(skb->sk); const int off = skb_transport_offset(skb); - const int len = skb->len - off; + int len = skb->len - off; + if ((up->pcflag & UDPLITE_SEND_CC) && up->pcslen < len) { + if (0 < up->pcslen) + len = up->pcslen; + udp_hdr(skb)->len = htons(up->pcslen); + } skb->ip_summed = CHECKSUM_NONE; /* no HW support for checksumming */ - return skb_checksum(skb, off, min(cscov, len), 0); + return skb_checksum(skb, off, len, 0); } extern void udplite4_register(void); -- cgit v1.2.3 From c7fd0d48bde943e228e9c28ce971a22d6a1744c4 Mon Sep 17 00:00:00 2001 From: Matthew Daley Date: Fri, 14 Oct 2011 18:45:03 +0000 Subject: x25: Validate incoming call user data lengths X.25 call user data is being copied in its entirety from incoming messages without consideration to the size of the destination buffers, leading to possible buffer overflows. Validate incoming call user data lengths before these copies are performed. It appears this issue was noticed some time ago, however nothing seemed to come of it: see http://www.spinics.net/lists/linux-x25/msg00043.html and commit 8db09f26f912f7c90c764806e804b558da520d4f. Signed-off-by: Matthew Daley Acked-by: Eric Dumazet Tested-by: Andrew Hendry Cc: stable Signed-off-by: David S. Miller --- net/x25/af_x25.c | 6 ++++++ net/x25/x25_in.c | 3 +++ 2 files changed, 9 insertions(+) diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index d30615419b4..a4bd1720e39 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -958,6 +958,12 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, goto out_clear_request; skb_pull(skb,len); + /* + * Ensure that the amount of call user data is valid. + */ + if (skb->len > X25_MAX_CUD_LEN) + goto out_clear_request; + /* * Find a listener for the particular address/cud pair. */ diff --git a/net/x25/x25_in.c b/net/x25/x25_in.c index 0b073b51b18..63488fd4885 100644 --- a/net/x25/x25_in.c +++ b/net/x25/x25_in.c @@ -127,6 +127,9 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp * Copy any Call User Data. */ if (skb->len > 0) { + if (skb->len > X25_MAX_CUD_LEN) + goto out_clear; + skb_copy_from_linear_data(skb, x25->calluserdata.cuddata, skb->len); -- cgit v1.2.3 From cb101ed2c3c7c0224d16953fe77bfb9d6c2cb9df Mon Sep 17 00:00:00 2001 From: Matthew Daley Date: Fri, 14 Oct 2011 18:45:04 +0000 Subject: x25: Handle undersized/fragmented skbs There are multiple locations in the X.25 packet layer where a skb is assumed to be of at least a certain size and that all its data is currently available at skb->data. These assumptions are not checked, hence buffer overreads may occur. Use pskb_may_pull to check these minimal size assumptions and ensure that data is available at skb->data when necessary, as well as use skb_copy_bits where needed. Signed-off-by: Matthew Daley Cc: Eric Dumazet Cc: Andrew Hendry Cc: stable Acked-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 31 ++++++++++++++++++++++++------- net/x25/x25_dev.c | 6 ++++++ net/x25/x25_facilities.c | 10 ++++++---- net/x25/x25_in.c | 40 +++++++++++++++++++++++++++++++++++----- net/x25/x25_link.c | 3 +++ net/x25/x25_subr.c | 14 +++++++++++++- 6 files changed, 87 insertions(+), 17 deletions(-) diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index a4bd1720e39..aa567b09ea9 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -91,7 +91,7 @@ int x25_parse_address_block(struct sk_buff *skb, int needed; int rc; - if (skb->len < 1) { + if (!pskb_may_pull(skb, 1)) { /* packet has no address block */ rc = 0; goto empty; @@ -100,7 +100,7 @@ int x25_parse_address_block(struct sk_buff *skb, len = *skb->data; needed = 1 + (len >> 4) + (len & 0x0f); - if (skb->len < needed) { + if (!pskb_may_pull(skb, needed)) { /* packet is too short to hold the addresses it claims to hold */ rc = -1; @@ -951,10 +951,10 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, * * Facilities length is mandatory in call request packets */ - if (skb->len < 1) + if (!pskb_may_pull(skb, 1)) goto out_clear_request; len = skb->data[0] + 1; - if (skb->len < len) + if (!pskb_may_pull(skb, len)) goto out_clear_request; skb_pull(skb,len); @@ -964,6 +964,13 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, if (skb->len > X25_MAX_CUD_LEN) goto out_clear_request; + /* + * Get all the call user data so it can be used in + * x25_find_listener and skb_copy_from_linear_data up ahead. + */ + if (!pskb_may_pull(skb, skb->len)) + goto out_clear_request; + /* * Find a listener for the particular address/cud pair. */ @@ -1172,6 +1179,9 @@ static int x25_sendmsg(struct kiocb *iocb, struct socket *sock, * byte of the user data is the logical value of the Q Bit. */ if (test_bit(X25_Q_BIT_FLAG, &x25->flags)) { + if (!pskb_may_pull(skb, 1)) + goto out_kfree_skb; + qbit = skb->data[0]; skb_pull(skb, 1); } @@ -1250,7 +1260,9 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock, struct x25_sock *x25 = x25_sk(sk); struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)msg->msg_name; size_t copied; - int qbit; + int qbit, header_len = x25->neighbour->extended ? + X25_EXT_MIN_LEN : X25_STD_MIN_LEN; + struct sk_buff *skb; unsigned char *asmptr; int rc = -ENOTCONN; @@ -1271,6 +1283,9 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock, skb = skb_dequeue(&x25->interrupt_in_queue); + if (!pskb_may_pull(skb, X25_STD_MIN_LEN)) + goto out_free_dgram; + skb_pull(skb, X25_STD_MIN_LEN); /* @@ -1291,10 +1306,12 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock, if (!skb) goto out; + if (!pskb_may_pull(skb, header_len)) + goto out_free_dgram; + qbit = (skb->data[0] & X25_Q_BIT) == X25_Q_BIT; - skb_pull(skb, x25->neighbour->extended ? - X25_EXT_MIN_LEN : X25_STD_MIN_LEN); + skb_pull(skb, header_len); if (test_bit(X25_Q_BIT_FLAG, &x25->flags)) { asmptr = skb_push(skb, 1); diff --git a/net/x25/x25_dev.c b/net/x25/x25_dev.c index e547ca1578c..fa2b41888bd 100644 --- a/net/x25/x25_dev.c +++ b/net/x25/x25_dev.c @@ -32,6 +32,9 @@ static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *nb) unsigned short frametype; unsigned int lci; + if (!pskb_may_pull(skb, X25_STD_MIN_LEN)) + return 0; + frametype = skb->data[2]; lci = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF); @@ -115,6 +118,9 @@ int x25_lapb_receive_frame(struct sk_buff *skb, struct net_device *dev, goto drop; } + if (!pskb_may_pull(skb, 1)) + return 0; + switch (skb->data[0]) { case X25_IFACE_DATA: diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c index f77e4e75f91..36384a1fa9f 100644 --- a/net/x25/x25_facilities.c +++ b/net/x25/x25_facilities.c @@ -44,7 +44,7 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask) { - unsigned char *p = skb->data; + unsigned char *p; unsigned int len; *vc_fac_mask = 0; @@ -60,14 +60,16 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, memset(dte_facs->called_ae, '\0', sizeof(dte_facs->called_ae)); memset(dte_facs->calling_ae, '\0', sizeof(dte_facs->calling_ae)); - if (skb->len < 1) + if (!pskb_may_pull(skb, 1)) return 0; - len = *p++; + len = skb->data[0]; - if (len >= skb->len) + if (!pskb_may_pull(skb, 1 + len)) return -1; + p = skb->data + 1; + while (len > 0) { switch (*p & X25_FAC_CLASS_MASK) { case X25_FAC_CLASS_A: diff --git a/net/x25/x25_in.c b/net/x25/x25_in.c index 63488fd4885..a49cd4ec551 100644 --- a/net/x25/x25_in.c +++ b/net/x25/x25_in.c @@ -107,6 +107,8 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp /* * Parse the data in the frame. */ + if (!pskb_may_pull(skb, X25_STD_MIN_LEN)) + goto out_clear; skb_pull(skb, X25_STD_MIN_LEN); len = x25_parse_address_block(skb, &source_addr, @@ -130,9 +132,8 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp if (skb->len > X25_MAX_CUD_LEN) goto out_clear; - skb_copy_from_linear_data(skb, - x25->calluserdata.cuddata, - skb->len); + skb_copy_bits(skb, 0, x25->calluserdata.cuddata, + skb->len); x25->calluserdata.cudlength = skb->len; } if (!sock_flag(sk, SOCK_DEAD)) @@ -140,6 +141,9 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp break; } case X25_CLEAR_REQUEST: + if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2)) + goto out_clear; + x25_write_internal(sk, X25_CLEAR_CONFIRMATION); x25_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]); break; @@ -167,6 +171,9 @@ static int x25_state2_machine(struct sock *sk, struct sk_buff *skb, int frametyp switch (frametype) { case X25_CLEAR_REQUEST: + if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2)) + goto out_clear; + x25_write_internal(sk, X25_CLEAR_CONFIRMATION); x25_disconnect(sk, 0, skb->data[3], skb->data[4]); break; @@ -180,6 +187,11 @@ static int x25_state2_machine(struct sock *sk, struct sk_buff *skb, int frametyp } return 0; + +out_clear: + x25_write_internal(sk, X25_CLEAR_REQUEST); + x25_start_t23timer(sk); + return 0; } /* @@ -209,6 +221,9 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp break; case X25_CLEAR_REQUEST: + if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2)) + goto out_clear; + x25_write_internal(sk, X25_CLEAR_CONFIRMATION); x25_disconnect(sk, 0, skb->data[3], skb->data[4]); break; @@ -307,6 +322,12 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp } return queued; + +out_clear: + x25_write_internal(sk, X25_CLEAR_REQUEST); + x25->state = X25_STATE_2; + x25_start_t23timer(sk); + return 0; } /* @@ -316,13 +337,13 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp */ static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametype) { + struct x25_sock *x25 = x25_sk(sk); + switch (frametype) { case X25_RESET_REQUEST: x25_write_internal(sk, X25_RESET_CONFIRMATION); case X25_RESET_CONFIRMATION: { - struct x25_sock *x25 = x25_sk(sk); - x25_stop_timer(sk); x25->condition = 0x00; x25->va = 0; @@ -334,6 +355,9 @@ static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametyp break; } case X25_CLEAR_REQUEST: + if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2)) + goto out_clear; + x25_write_internal(sk, X25_CLEAR_CONFIRMATION); x25_disconnect(sk, 0, skb->data[3], skb->data[4]); break; @@ -343,6 +367,12 @@ static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametyp } return 0; + +out_clear: + x25_write_internal(sk, X25_CLEAR_REQUEST); + x25->state = X25_STATE_2; + x25_start_t23timer(sk); + return 0; } /* Higher level upcall for a LAPB frame */ diff --git a/net/x25/x25_link.c b/net/x25/x25_link.c index 037958ff8ee..4acacf3c661 100644 --- a/net/x25/x25_link.c +++ b/net/x25/x25_link.c @@ -90,6 +90,9 @@ void x25_link_control(struct sk_buff *skb, struct x25_neigh *nb, break; case X25_DIAGNOSTIC: + if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 4)) + break; + printk(KERN_WARNING "x25: diagnostic #%d - %02X %02X %02X\n", skb->data[3], skb->data[4], skb->data[5], skb->data[6]); diff --git a/net/x25/x25_subr.c b/net/x25/x25_subr.c index 24a342ebc7f..5170d52bfd9 100644 --- a/net/x25/x25_subr.c +++ b/net/x25/x25_subr.c @@ -269,7 +269,11 @@ int x25_decode(struct sock *sk, struct sk_buff *skb, int *ns, int *nr, int *q, int *d, int *m) { struct x25_sock *x25 = x25_sk(sk); - unsigned char *frame = skb->data; + unsigned char *frame; + + if (!pskb_may_pull(skb, X25_STD_MIN_LEN)) + return X25_ILLEGAL; + frame = skb->data; *ns = *nr = *q = *d = *m = 0; @@ -294,6 +298,10 @@ int x25_decode(struct sock *sk, struct sk_buff *skb, int *ns, int *nr, int *q, if (frame[2] == X25_RR || frame[2] == X25_RNR || frame[2] == X25_REJ) { + if (!pskb_may_pull(skb, X25_EXT_MIN_LEN)) + return X25_ILLEGAL; + frame = skb->data; + *nr = (frame[3] >> 1) & 0x7F; return frame[2]; } @@ -308,6 +316,10 @@ int x25_decode(struct sock *sk, struct sk_buff *skb, int *ns, int *nr, int *q, if (x25->neighbour->extended) { if ((frame[2] & 0x01) == X25_DATA) { + if (!pskb_may_pull(skb, X25_EXT_MIN_LEN)) + return X25_ILLEGAL; + frame = skb->data; + *q = (frame[0] & X25_Q_BIT) == X25_Q_BIT; *d = (frame[0] & X25_D_BIT) == X25_D_BIT; *m = (frame[3] & X25_EXT_M_BIT) == X25_EXT_M_BIT; -- cgit v1.2.3 From 7f81e25befdfb3272345a2e775f520e1d515fa20 Mon Sep 17 00:00:00 2001 From: Matthew Daley Date: Fri, 14 Oct 2011 18:45:05 +0000 Subject: x25: Prevent skb overreads when checking call user data x25_find_listener does not check that the amount of call user data given in the skb is big enough in per-socket comparisons, hence buffer overreads may occur. Fix this by adding a check. Signed-off-by: Matthew Daley Cc: Eric Dumazet Cc: Andrew Hendry Cc: stable Acked-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index aa567b09ea9..5f03e4ea65b 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -295,7 +295,8 @@ static struct sock *x25_find_listener(struct x25_address *addr, * Found a listening socket, now check the incoming * call user data vs this sockets call user data */ - if(skb->len > 0 && x25_sk(s)->cudmatchlength > 0) { + if (x25_sk(s)->cudmatchlength > 0 && + skb->len >= x25_sk(s)->cudmatchlength) { if((memcmp(x25_sk(s)->calluserdata.cuddata, skb->data, x25_sk(s)->cudmatchlength)) == 0) { -- cgit v1.2.3 From 899e3ee404961a90b828ad527573aaaac39f0ab1 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 17 Oct 2011 21:06:23 -0700 Subject: Linux 3.1-rc10 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 31f967c31e7..2652089bf54 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 1 SUBLEVEL = 0 -EXTRAVERSION = -rc9 +EXTRAVERSION = -rc10 NAME = "Divemaster Edition" # *DOCUMENTATION* -- cgit v1.2.3 From e22469ca88a8f1f6fe47adbf5e5ce0906aec07cd Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 17 Oct 2011 13:27:34 +0200 Subject: ttm: Fix error-path using an uninitialized value Pointed out by Michel Daenzer. Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/ttm/ttm_bo_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index ae3c6f5dd2b..082fcaea583 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -321,7 +321,7 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, struct ttm_mem_type_manager *man = &bdev->man[new_mem->mem_type]; struct ttm_tt *ttm = bo->ttm; struct ttm_mem_reg *old_mem = &bo->mem; - struct ttm_mem_reg old_copy; + struct ttm_mem_reg old_copy = *old_mem; void *old_iomap; void *new_iomap; int ret; -- cgit v1.2.3 From 3a6dea31453a101bd5e9e9c89a79f4fcb6b0342e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 12 Oct 2011 18:44:32 -0400 Subject: drm/radeon/kms/DCE4.1: fix dig encoder to transmitter mapping llano has fully routeable dig encoders similar to DCE3.2 while ontario has a hardcoded mapping similar to DCE4.0. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_encoders.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 8a171b21b45..a90d9eeb96a 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -1756,10 +1756,15 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) if (ASIC_IS_DCE4(rdev)) { dig = radeon_encoder->enc_priv; if (ASIC_IS_DCE41(rdev)) { - if (dig->linkb) - return 1; - else - return 0; + /* ontario follows DCE4 */ + if (rdev->family == CHIP_PALM) { + if (dig->linkb) + return 1; + else + return 0; + } else + /* llano follows DCE3.2 */ + return radeon_crtc->crtc_id; } else { switch (radeon_encoder->encoder_id) { case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: -- cgit v1.2.3 From 09cc6506f9e234b2ead60398ebb88c4b44421a93 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 12 Oct 2011 18:44:33 -0400 Subject: drm/radeon/kms/DCE4.1: ss is not supported on the internal pplls It's handled via external clock. It should already be protected by the external ss flag, but add an explicit check just in case. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/atombios_crtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index c742944d380..a515b2a09d8 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -466,7 +466,7 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc, return; } args.v2.ucEnable = enable; - if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK)) + if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK) || ASIC_IS_DCE41(rdev)) args.v2.ucEnable = ATOM_DISABLE; } else if (ASIC_IS_DCE3(rdev)) { args.v1.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); -- cgit v1.2.3 From a4863ca93ccc52a83e7fbfc068b411b7faa03805 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 12 Oct 2011 18:49:53 -0400 Subject: drm/radeon/kms/DCE4.1: fix Select_CrtcSource EncodeMode setting for DP bridges (v2) Settings in this table reflect the physical panel/connector rather than the internal dig encoding. v2: fix typo for DRM_MODE_CONNECTOR_VGA case. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_encoders.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index a90d9eeb96a..eb3f6dc6df8 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -1638,7 +1638,17 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) break; case 2: args.v2.ucCRTC = radeon_crtc->crtc_id; - args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder); + if (radeon_encoder_is_dp_bridge(encoder)) { + struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); + + if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) + args.v2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS; + else if (connector->connector_type == DRM_MODE_CONNECTOR_VGA) + args.v2.ucEncodeMode = ATOM_ENCODER_MODE_CRT; + else + args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder); + } else + args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder); switch (radeon_encoder->encoder_id) { case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: -- cgit v1.2.3 From bcd5cff7216f9b2de0a148cc355eac199dc6f1cf Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 17 Oct 2011 11:50:30 +0200 Subject: cputimer: Cure lock inversion There's a lock inversion between the cputimer->lock and rq->lock; notably the two callchains involved are: update_rlimit_cpu() sighand->siglock set_process_cpu_timer() cpu_timer_sample_group() thread_group_cputimer() cputimer->lock thread_group_cputime() task_sched_runtime() ->pi_lock rq->lock scheduler_tick() rq->lock task_tick_fair() update_curr() account_group_exec() cputimer->lock Where the first one is enabling a CLOCK_PROCESS_CPUTIME_ID timer, and the second one is keeping up-to-date. This problem was introduced by e8abccb7193 ("posix-cpu-timers: Cure SMP accounting oddities"). Cure the problem by removing the cputimer->lock and rq->lock nesting, this leaves concurrent enablers doing duplicate work, but the time wasted should be on the same order otherwise wasted spinning on the lock and the greater-than assignment filter should ensure we preserve monotonicity. Reported-by: Dave Jones Reported-by: Simon Kirby Signed-off-by: Peter Zijlstra Cc: stable@kernel.org Cc: Linus Torvalds Cc: Martin Schwidefsky Link: http://lkml.kernel.org/r/1318928713.21167.4.camel@twins Signed-off-by: Thomas Gleixner --- kernel/posix-cpu-timers.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index c8008dd58ef..640ded8f5c4 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c @@ -274,9 +274,7 @@ void thread_group_cputimer(struct task_struct *tsk, struct task_cputime *times) struct task_cputime sum; unsigned long flags; - spin_lock_irqsave(&cputimer->lock, flags); if (!cputimer->running) { - cputimer->running = 1; /* * The POSIX timer interface allows for absolute time expiry * values through the TIMER_ABSTIME flag, therefore we have @@ -284,8 +282,11 @@ void thread_group_cputimer(struct task_struct *tsk, struct task_cputime *times) * it. */ thread_group_cputime(tsk, &sum); + spin_lock_irqsave(&cputimer->lock, flags); + cputimer->running = 1; update_gt_cputime(&cputimer->cputime, &sum); - } + } else + spin_lock_irqsave(&cputimer->lock, flags); *times = cputimer->cputime; spin_unlock_irqrestore(&cputimer->lock, flags); } -- cgit v1.2.3 From 31901264511cf20c5ed33b8649a3ca9ce28df60b Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Sun, 16 Oct 2011 18:53:37 +0200 Subject: batman-adv: fix tt_local_reset_flags() function Currently the counter of tt_local_entry structures (tt_local_num) is incremented each time the tt_local_reset_flags() is invoked causing the node to send wrong TT_REPONSE packets containing a copy of non-initialised memory thus corrupting other nodes global translation table and making higher level communication impossible. Reported-by: Junkeun Song Signed-off-by: Antonio Quartulli Acked-by: Junkeun Song Signed-off-by: Marek Lindner --- net/batman-adv/translation-table.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index fb6931d00cd..f599db9dbec 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -1668,6 +1668,8 @@ static void tt_local_reset_flags(struct bat_priv *bat_priv, uint16_t flags) rcu_read_lock(); hlist_for_each_entry_rcu(tt_local_entry, node, head, hash_entry) { + if (!(tt_local_entry->flags & flags)) + continue; tt_local_entry->flags &= ~flags; atomic_inc(&bat_priv->num_local_tt); } -- cgit v1.2.3 From 9d8523931f7f5eb8900077f0da0fbe6b8ad0010b Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Mon, 17 Oct 2011 14:25:13 +0200 Subject: batman-adv: correctly set the data field in the TT_REPONSE packet In the TT_RESPONSE packet, the number of carried entries is not correctly set. This leads to a wrong interpretation of the packet payload on the receiver side causing random entries to be added to the global translation table. Therefore the latter gets always corrupted, triggering a table recovery all the time. Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- net/batman-adv/translation-table.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index f599db9dbec..ef1acfd7653 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -999,7 +999,6 @@ static struct sk_buff *tt_response_fill_table(uint16_t tt_len, uint8_t ttvn, tt_response = (struct tt_query_packet *)skb_put(skb, tt_query_size + tt_len); tt_response->ttvn = ttvn; - tt_response->tt_data = htons(tt_tot); tt_change = (struct tt_change *)(skb->data + tt_query_size); tt_count = 0; @@ -1025,6 +1024,10 @@ static struct sk_buff *tt_response_fill_table(uint16_t tt_len, uint8_t ttvn, } rcu_read_unlock(); + /* store in the message the number of entries we have successfully + * copied */ + tt_response->tt_data = htons(tt_count); + out: return skb; } -- cgit v1.2.3 From 1ce5cce895309862d2c35d922816adebe094fe4a Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Thu, 6 Oct 2011 11:19:41 +0000 Subject: bridge: fix hang on removal of bridge via netlink Need to cleanup bridge device timers and ports when being bridge device is being removed via netlink. This fixes the problem of observed when doing: ip link add br0 type bridge ip link set dev eth1 master br0 ip link set br0 up ip link del br0 which would cause br0 to hang in unregister_netdev because of leftover reference count. Reported-by: Sridhar Samudrala Signed-off-by: Stephen Hemminger Acked-by: Sridhar Samudrala Signed-off-by: David S. Miller --- net/bridge/br_if.c | 9 +++++---- net/bridge/br_netlink.c | 1 + net/bridge/br_private.h | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index e73815456ad..1d420f64ff2 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -161,9 +161,10 @@ static void del_nbp(struct net_bridge_port *p) call_rcu(&p->rcu, destroy_nbp_rcu); } -/* called with RTNL */ -static void del_br(struct net_bridge *br, struct list_head *head) +/* Delete bridge device */ +void br_dev_delete(struct net_device *dev, struct list_head *head) { + struct net_bridge *br = netdev_priv(dev); struct net_bridge_port *p, *n; list_for_each_entry_safe(p, n, &br->port_list, list) { @@ -268,7 +269,7 @@ int br_del_bridge(struct net *net, const char *name) } else - del_br(netdev_priv(dev), NULL); + br_dev_delete(dev, NULL); rtnl_unlock(); return ret; @@ -449,7 +450,7 @@ void __net_exit br_net_exit(struct net *net) rtnl_lock(); for_each_netdev(net, dev) if (dev->priv_flags & IFF_EBRIDGE) - del_br(netdev_priv(dev), &list); + br_dev_delete(dev, &list); unregister_netdevice_many(&list); rtnl_unlock(); diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 5b1ed1ba9aa..e5f9ece3c9a 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -210,6 +210,7 @@ static struct rtnl_link_ops br_link_ops __read_mostly = { .priv_size = sizeof(struct net_bridge), .setup = br_dev_setup, .validate = br_validate, + .dellink = br_dev_delete, }; int __init br_netlink_init(void) diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 78cc364997d..857a021deea 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -294,6 +294,7 @@ static inline int br_is_root_bridge(const struct net_bridge *br) /* br_device.c */ extern void br_dev_setup(struct net_device *dev); +extern void br_dev_delete(struct net_device *dev, struct list_head *list); extern netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev); #ifdef CONFIG_NET_POLL_CONTROLLER -- cgit v1.2.3 From 835acf5da239b91edb9f7ebe36516999e156e6ee Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 7 Oct 2011 05:35:46 +0000 Subject: l2tp: fix a potential skb leak in l2tp_xmit_skb() l2tp_xmit_skb() can leak one skb if skb_cow_head() returns an error. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/l2tp/l2tp_core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index ad4ac2601a5..34b2ddeacb6 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -1045,8 +1045,10 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len headroom = NET_SKB_PAD + sizeof(struct iphdr) + uhlen + hdr_len; old_headroom = skb_headroom(skb); - if (skb_cow_head(skb, headroom)) + if (skb_cow_head(skb, headroom)) { + dev_kfree_skb(skb); goto abort; + } new_headroom = skb_headroom(skb); skb_orphan(skb); -- cgit v1.2.3 From 6230c9b4f8957c8938ee4cf2d03166d3c2dc89de Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Fri, 7 Oct 2011 09:40:59 +0000 Subject: bluetooth: Properly clone LSM attributes to newly created child connections The Bluetooth stack has internal connection handlers for all of the various Bluetooth protocols, and unfortunately, they are currently lacking the LSM hooks found in the core network stack's connection handlers. I say unfortunately, because this can cause problems for users who have have an LSM enabled and are using certain Bluetooth devices. See one problem report below: * http://bugzilla.redhat.com/show_bug.cgi?id=741703 In order to keep things simple at this point in time, this patch fixes the problem by cloning the parent socket's LSM attributes to the newly created child socket. If we decide we need a more elaborate LSM marking mechanism for Bluetooth (I somewhat doubt this) we can always revisit this decision in the future. Reported-by: James M. Cape Signed-off-by: Paul Moore Acked-by: James Morris Signed-off-by: David S. Miller --- net/bluetooth/l2cap_sock.c | 4 ++++ net/bluetooth/rfcomm/sock.c | 3 +++ net/bluetooth/sco.c | 5 ++++- security/security.c | 1 + 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 61f1f623091..e8292369cdc 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -26,6 +26,8 @@ /* Bluetooth L2CAP sockets. */ +#include + #include #include #include @@ -933,6 +935,8 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent) chan->force_reliable = pchan->force_reliable; chan->flushable = pchan->flushable; chan->force_active = pchan->force_active; + + security_sk_clone(parent, sk); } else { switch (sk->sk_type) { diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 482722bbc7a..5417f612732 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -264,6 +265,8 @@ static void rfcomm_sock_init(struct sock *sk, struct sock *parent) pi->sec_level = rfcomm_pi(parent)->sec_level; pi->role_switch = rfcomm_pi(parent)->role_switch; + + security_sk_clone(parent, sk); } else { pi->dlc->defer_setup = 0; diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 8270f05e3f1..a324b009e34 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -403,8 +404,10 @@ static void sco_sock_init(struct sock *sk, struct sock *parent) { BT_DBG("sk %p", sk); - if (parent) + if (parent) { sk->sk_type = parent->sk_type; + security_sk_clone(parent, sk); + } } static struct proto sco_proto = { diff --git a/security/security.c b/security/security.c index 0e4fccfef12..d9e15339092 100644 --- a/security/security.c +++ b/security/security.c @@ -1097,6 +1097,7 @@ void security_sk_clone(const struct sock *sk, struct sock *newsk) { security_ops->sk_clone_security(sk, newsk); } +EXPORT_SYMBOL(security_sk_clone); void security_sk_classify_flow(struct sock *sk, struct flowi *fl) { -- cgit v1.2.3 From d5123480b1d6f7d1a5fe1a13520cef88fb5d4c84 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Tue, 11 Oct 2011 16:08:11 +0000 Subject: netconsole: enable netconsole can make net_device refcnt incorrent There is no check if netconsole is enabled current. so when exec echo 1 > enabled; the reference of net_device will increment always. Signed-off-by: Gao feng Acked-by: Flavio Leitner Signed-off-by: David S. Miller --- drivers/net/netconsole.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index ed2a3977c6e..e8882023576 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -307,6 +307,11 @@ static ssize_t store_enabled(struct netconsole_target *nt, return err; if (enabled < 0 || enabled > 1) return -EINVAL; + if (enabled == nt->enabled) { + printk(KERN_INFO "netconsole: network logging has already %s\n", + nt->enabled ? "started" : "stopped"); + return -EINVAL; + } if (enabled) { /* 1 */ -- cgit v1.2.3 From e730c82347b9dc75914da998c44c3f348965db41 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 11 Oct 2011 23:00:41 +0000 Subject: tg3: negate USE_PHYLIB flag check USE_PHYLIB flag in tg3_remove_one() is being checked incorrectly. This results tg3_phy_fini->phy_disconnect is never called and when tg3 module is removed. In my case this resulted in panics in phy_state_machine calling function phydev->adjust_link. So correct this check. Signed-off-by: Jiri Pirko Acked-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 4a1374df608..c11a2b8327f 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -15577,7 +15577,7 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev) cancel_work_sync(&tp->reset_task); - if (!tg3_flag(tp, USE_PHYLIB)) { + if (tg3_flag(tp, USE_PHYLIB)) { tg3_phy_fini(tp); tg3_mdio_fini(tp); } -- cgit v1.2.3 From 28c213793c994e4aac5f669ce856b5682a549bbb Mon Sep 17 00:00:00 2001 From: Phil Edworthy Date: Wed, 12 Oct 2011 02:29:39 +0000 Subject: smsc911x: Add support for SMSC LAN89218 LAN89218 is register compatible with LAN911x. Signed-off-by: Phil Edworthy Signed-off-by: David S. Miller --- drivers/net/smsc911x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index b9016a30cdc..c90ddb61cc5 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -26,6 +26,7 @@ * LAN9215, LAN9216, LAN9217, LAN9218 * LAN9210, LAN9211 * LAN9220, LAN9221 + * LAN89218 * */ @@ -1983,6 +1984,7 @@ static int __devinit smsc911x_init(struct net_device *dev) case 0x01170000: case 0x01160000: case 0x01150000: + case 0x218A0000: /* LAN911[5678] family */ pdata->generation = pdata->idrev & 0x0000FFFF; break; -- cgit v1.2.3 From 4d97480b1806e883eb1c7889d4e7a87e936e06d9 Mon Sep 17 00:00:00 2001 From: Mitsuo Hayasaka Date: Wed, 12 Oct 2011 16:04:29 +0000 Subject: bonding: use local function pointer of bond->recv_probe in bond_handle_frame The bond->recv_probe is called in bond_handle_frame() when a packet is received, but bond_close() sets it to NULL. So, a panic occurs when both functions work in parallel. Why this happen: After null pointer check of bond->recv_probe, an sk_buff is duplicated and bond->recv_probe is called in bond_handle_frame. So, a panic occurs when bond_close() is called between the check and call of bond->recv_probe. Patch: This patch uses a local function pointer of bond->recv_probe in bond_handle_frame(). So, it can avoid the null pointer dereference. Signed-off-by: Mitsuo Hayasaka Cc: Jay Vosburgh Cc: Andy Gospodarek Cc: Eric Dumazet Cc: WANG Cong Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 6d79b78cfc7..de3d351ccb6 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1435,6 +1435,8 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb) struct sk_buff *skb = *pskb; struct slave *slave; struct bonding *bond; + void (*recv_probe)(struct sk_buff *, struct bonding *, + struct slave *); skb = skb_share_check(skb, GFP_ATOMIC); if (unlikely(!skb)) @@ -1448,11 +1450,12 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb) if (bond->params.arp_interval) slave->dev->last_rx = jiffies; - if (bond->recv_probe) { + recv_probe = ACCESS_ONCE(bond->recv_probe); + if (recv_probe) { struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC); if (likely(nskb)) { - bond->recv_probe(nskb, bond, slave); + recv_probe(nskb, bond, slave); dev_kfree_skb(nskb); } } -- cgit v1.2.3 From 8bae8bd6cb24eecad9fda3e125d36ab9c67d3fd7 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 17 Oct 2011 17:01:47 +0000 Subject: pptp: fix skb leak in pptp_xmit() In case we cant transmit skb, we must free it Signed-off-by: Eric Dumazet CC: Dmitry Kozlov Signed-off-by: David S. Miller --- drivers/net/pptp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/pptp.c b/drivers/net/pptp.c index eae542a7e98..9c0403d0107 100644 --- a/drivers/net/pptp.c +++ b/drivers/net/pptp.c @@ -285,8 +285,10 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) ip_send_check(iph); ip_local_out(skb); + return 1; tx_error: + kfree_skb(skb); return 1; } -- cgit v1.2.3 From 58af19e387d8821927e49be3f467da5e6a0aa8fd Mon Sep 17 00:00:00 2001 From: KOVACS Krisztian Date: Tue, 18 Oct 2011 10:17:35 +0000 Subject: tproxy: copy transparent flag when creating a time wait The transparent socket option setting was not copied to the time wait socket when an inet socket was being replaced by a time wait socket. This broke the --transparent option of the socket match and may have caused that FIN packets belonging to sockets in FIN_WAIT2 or TIME_WAIT state were being dropped by the packet filter. Signed-off-by: KOVACS Krisztian Signed-off-by: David S. Miller --- net/ipv4/tcp_minisocks.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index d2fe4e06b47..0ce3d06dce6 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -328,6 +328,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo) struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw); const int rto = (icsk->icsk_rto << 2) - (icsk->icsk_rto >> 1); + tw->tw_transparent = inet_sk(sk)->transparent; tw->tw_rcv_wscale = tp->rx_opt.rcv_wscale; tcptw->tw_rcv_nxt = tp->rcv_nxt; tcptw->tw_snd_nxt = tp->snd_nxt; -- cgit v1.2.3 From 4ea2739ea89883ddf79980a8aa27d5e57093e464 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 17 Oct 2011 17:59:53 +0000 Subject: pptp: pptp_rcv_core() misses pskb_may_pull() call e1000e uses paged frags, so any layer incorrectly pulling bytes from skb can trigger a BUG in skb_pull() [951.142737] [] skb_pull+0x15/0x17 [951.142737] [] pptp_rcv_core+0x126/0x19a [pptp] [951.152725] [] sk_receive_skb+0x69/0x105 [951.163558] [] pptp_rcv+0xc8/0xdc [pptp] [951.165092] [] gre_rcv+0x62/0x75 [gre] [951.165092] [] ip_local_deliver_finish+0x150/0x1c1 [951.177599] [] ? ip_local_deliver_finish+0x0/0x1c1 [951.177599] [] NF_HOOK.clone.7+0x51/0x58 [951.177599] [] ip_local_deliver+0x51/0x55 [951.177599] [] ip_rcv_finish+0x31a/0x33e [951.177599] [] ? ip_rcv_finish+0x0/0x33e [951.204898] [] NF_HOOK.clone.7+0x51/0x58 [951.214651] [] ip_rcv+0x21b/0x246 pptp_rcv_core() is a nice example of a function assuming everything it needs is available in skb head. Reported-by: Bradley Peterson Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/pptp.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/net/pptp.c b/drivers/net/pptp.c index 9c0403d0107..89f829f5f72 100644 --- a/drivers/net/pptp.c +++ b/drivers/net/pptp.c @@ -307,11 +307,18 @@ static int pptp_rcv_core(struct sock *sk, struct sk_buff *skb) } header = (struct pptp_gre_header *)(skb->data); + headersize = sizeof(*header); /* test if acknowledgement present */ if (PPTP_GRE_IS_A(header->ver)) { - __u32 ack = (PPTP_GRE_IS_S(header->flags)) ? - header->ack : header->seq; /* ack in different place if S = 0 */ + __u32 ack; + + if (!pskb_may_pull(skb, headersize)) + goto drop; + header = (struct pptp_gre_header *)(skb->data); + + /* ack in different place if S = 0 */ + ack = PPTP_GRE_IS_S(header->flags) ? header->ack : header->seq; ack = ntohl(ack); @@ -320,21 +327,18 @@ static int pptp_rcv_core(struct sock *sk, struct sk_buff *skb) /* also handle sequence number wrap-around */ if (WRAPPED(ack, opt->ack_recv)) opt->ack_recv = ack; + } else { + headersize -= sizeof(header->ack); } - /* test if payload present */ if (!PPTP_GRE_IS_S(header->flags)) goto drop; - headersize = sizeof(*header); payload_len = ntohs(header->payload_len); seq = ntohl(header->seq); - /* no ack present? */ - if (!PPTP_GRE_IS_A(header->ver)) - headersize -= sizeof(header->ack); /* check for incomplete packet (length smaller than expected) */ - if (skb->len - headersize < payload_len) + if (!pskb_may_pull(skb, headersize + payload_len)) goto drop; payload = skb->data + headersize; -- cgit v1.2.3 From 5a6e8482a16e61250a9121fc9ec719ab0529e760 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 18 Oct 2011 20:10:05 -0400 Subject: drm/radeon/kms/atom: fix handling of FB scratch indices FB scratch indices are dword indices, but we were treating them as byte indices. As such, we were getting the wrong FB scratch data for non-0 indices. Fix the indices and guard the indexing against indices larger than the scratch allocation. Fixes memory corruption on some boards if data was written past the end of the FB scratch array. Signed-off-by: Alex Deucher Reported-by: Dave Airlie Tested-by: Dave Airlie Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/atom.c | 15 +++++++++++++-- drivers/gpu/drm/radeon/atom.h | 1 + 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index e88c64417a8..14cc88aaf3a 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c @@ -277,7 +277,12 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr, case ATOM_ARG_FB: idx = U8(*ptr); (*ptr)++; - val = gctx->scratch[((gctx->fb_base + idx) / 4)]; + if ((gctx->fb_base + (idx * 4)) > gctx->scratch_size_bytes) { + DRM_ERROR("ATOM: fb read beyond scratch region: %d vs. %d\n", + gctx->fb_base + (idx * 4), gctx->scratch_size_bytes); + val = 0; + } else + val = gctx->scratch[(gctx->fb_base / 4) + idx]; if (print) DEBUG("FB[0x%02X]", idx); break; @@ -531,7 +536,11 @@ static void atom_put_dst(atom_exec_context *ctx, int arg, uint8_t attr, case ATOM_ARG_FB: idx = U8(*ptr); (*ptr)++; - gctx->scratch[((gctx->fb_base + idx) / 4)] = val; + if ((gctx->fb_base + (idx * 4)) > gctx->scratch_size_bytes) { + DRM_ERROR("ATOM: fb write beyond scratch region: %d vs. %d\n", + gctx->fb_base + (idx * 4), gctx->scratch_size_bytes); + } else + gctx->scratch[(gctx->fb_base / 4) + idx] = val; DEBUG("FB[0x%02X]", idx); break; case ATOM_ARG_PLL: @@ -1370,11 +1379,13 @@ int atom_allocate_fb_scratch(struct atom_context *ctx) usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024; } + ctx->scratch_size_bytes = 0; if (usage_bytes == 0) usage_bytes = 20 * 1024; /* allocate some scratch memory */ ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL); if (!ctx->scratch) return -ENOMEM; + ctx->scratch_size_bytes = usage_bytes; return 0; } diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h index a589a55b223..93cfe2086ba 100644 --- a/drivers/gpu/drm/radeon/atom.h +++ b/drivers/gpu/drm/radeon/atom.h @@ -137,6 +137,7 @@ struct atom_context { int cs_equal, cs_above; int io_mode; uint32_t *scratch; + int scratch_size_bytes; }; extern int atom_debug; -- cgit v1.2.3 From e58fced201ad6e6cb673f07499919c3b20792d94 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Wed, 12 Oct 2011 17:59:26 -0300 Subject: [media] videodev: fix a NULL pointer dereference in v4l2_device_release() The change in 8280b66 does not cover the case when v4l2_dev is already NULL, fix that. With a Kinect sensor, seen as an USB camera using GSPCA in this context, a NULL pointer dereference BUG can be triggered by just unplugging the device after the camera driver has been loaded. Signed-off-by: Antonio Ospite Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index d7215651772..a5c9ed128b9 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -181,7 +181,7 @@ static void v4l2_device_release(struct device *cd) * TODO: In the long run all drivers that use v4l2_device should use the * v4l2_device release callback. This check will then be unnecessary. */ - if (v4l2_dev->release == NULL) + if (v4l2_dev && v4l2_dev->release == NULL) v4l2_dev = NULL; /* Release video_device and perform other -- cgit v1.2.3 From 34b1901abdf8793cd679d0e48012d3d7570f88d6 Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Thu, 13 Oct 2011 09:56:19 +0000 Subject: ehea: Change maintainer to me MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Breno Leitao has passed the maintainership to me. Signed-off-by: Thadeu Lima de Souza Cascardo Cc: Breno Leitao Acked-by: Breno Leitão Signed-off-by: David S. Miller --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 5483e0c93b4..b3bc88d9c03 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2460,7 +2460,7 @@ S: Supported F: drivers/infiniband/hw/ehca/ EHEA (IBM pSeries eHEA 10Gb ethernet adapter) DRIVER -M: Breno Leitao +M: Thadeu Lima de Souza Cascardo L: netdev@vger.kernel.org S: Maintained F: drivers/net/ehea/ -- cgit v1.2.3 From 649b3b8c4e8681de443b4dc9e387c3036369e02e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?fran=C3=A7ois=20romieu?= Date: Fri, 14 Oct 2011 00:57:45 +0000 Subject: r8169: fix driver shutdown WoL regression. Due to commit 92fc43b4159b518f5baae57301f26d770b0834c9 ("r8169: modify the flow of the hw reset."), rtl8169_hw_reset stomps during driver shutdown on RxConfig bits which are needed for WOL on some versions of the hardware. As these bits were formerly set from the r81{0x, 68}_pll_power_down methods, factor them out for use in the driver shutdown (rtl_shutdown) handler. I favored __rtl8169_get_wol() -hardware state indication- over RTL_FEATURE_WOL as the latter has become a good candidate for removal. Signed-off-by: Francois Romieu Cc: Hayes Tested-by: Marc Ballarin Signed-off-by: David S. Miller --- drivers/net/r8169.c | 88 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 32 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index c2366701792..24219ec0de1 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -3316,6 +3316,37 @@ static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp) } } +static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + + switch (tp->mac_version) { + case RTL_GIGA_MAC_VER_29: + case RTL_GIGA_MAC_VER_30: + case RTL_GIGA_MAC_VER_32: + case RTL_GIGA_MAC_VER_33: + case RTL_GIGA_MAC_VER_34: + RTL_W32(RxConfig, RTL_R32(RxConfig) | + AcceptBroadcast | AcceptMulticast | AcceptMyPhys); + break; + default: + break; + } +} + +static bool rtl_wol_pll_power_down(struct rtl8169_private *tp) +{ + if (!(__rtl8169_get_wol(tp) & WAKE_ANY)) + return false; + + rtl_writephy(tp, 0x1f, 0x0000); + rtl_writephy(tp, MII_BMCR, 0x0000); + + rtl_wol_suspend_quirk(tp); + + return true; +} + static void r810x_phy_power_down(struct rtl8169_private *tp) { rtl_writephy(tp, 0x1f, 0x0000); @@ -3330,18 +3361,8 @@ static void r810x_phy_power_up(struct rtl8169_private *tp) static void r810x_pll_power_down(struct rtl8169_private *tp) { - void __iomem *ioaddr = tp->mmio_addr; - - if (__rtl8169_get_wol(tp) & WAKE_ANY) { - rtl_writephy(tp, 0x1f, 0x0000); - rtl_writephy(tp, MII_BMCR, 0x0000); - - if (tp->mac_version == RTL_GIGA_MAC_VER_29 || - tp->mac_version == RTL_GIGA_MAC_VER_30) - RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast | - AcceptMulticast | AcceptMyPhys); + if (rtl_wol_pll_power_down(tp)) return; - } r810x_phy_power_down(tp); } @@ -3430,17 +3451,8 @@ static void r8168_pll_power_down(struct rtl8169_private *tp) tp->mac_version == RTL_GIGA_MAC_VER_33) rtl_ephy_write(ioaddr, 0x19, 0xff64); - if (__rtl8169_get_wol(tp) & WAKE_ANY) { - rtl_writephy(tp, 0x1f, 0x0000); - rtl_writephy(tp, MII_BMCR, 0x0000); - - if (tp->mac_version == RTL_GIGA_MAC_VER_32 || - tp->mac_version == RTL_GIGA_MAC_VER_33 || - tp->mac_version == RTL_GIGA_MAC_VER_34) - RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast | - AcceptMulticast | AcceptMyPhys); + if (rtl_wol_pll_power_down(tp)) return; - } r8168_phy_power_down(tp); @@ -5788,11 +5800,30 @@ static const struct dev_pm_ops rtl8169_pm_ops = { #endif /* !CONFIG_PM */ +static void rtl_wol_shutdown_quirk(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + + /* WoL fails with 8168b when the receiver is disabled. */ + switch (tp->mac_version) { + case RTL_GIGA_MAC_VER_11: + case RTL_GIGA_MAC_VER_12: + case RTL_GIGA_MAC_VER_17: + pci_clear_master(tp->pci_dev); + + RTL_W8(ChipCmd, CmdRxEnb); + /* PCI commit */ + RTL_R8(ChipCmd); + break; + default: + break; + } +} + static void rtl_shutdown(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; rtl8169_net_suspend(dev); @@ -5806,16 +5837,9 @@ static void rtl_shutdown(struct pci_dev *pdev) spin_unlock_irq(&tp->lock); if (system_state == SYSTEM_POWER_OFF) { - /* WoL fails with 8168b when the receiver is disabled. */ - if ((tp->mac_version == RTL_GIGA_MAC_VER_11 || - tp->mac_version == RTL_GIGA_MAC_VER_12 || - tp->mac_version == RTL_GIGA_MAC_VER_17) && - (tp->features & RTL_FEATURE_WOL)) { - pci_clear_master(pdev); - - RTL_W8(ChipCmd, CmdRxEnb); - /* PCI commit */ - RTL_R8(ChipCmd); + if (__rtl8169_get_wol(tp) & WAKE_ANY) { + rtl_wol_suspend_quirk(tp); + rtl_wol_shutdown_quirk(tp); } pci_wake_from_d3(pdev, true); -- cgit v1.2.3 From 1b23a3e3d1b969e285c57a2d38f3739283ecfb80 Mon Sep 17 00:00:00 2001 From: hayeswang Date: Thu, 13 Oct 2011 20:14:37 +0000 Subject: r8169: fix wrong eee setting for rlt8111evl Correct the wrong parameter for setting EEE for RTL8111E-VL. Signed-off-by: Hayes Wang Signed-off-by: David S. Miller --- drivers/net/r8169.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 24219ec0de1..6d657cabb95 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -2859,7 +2859,7 @@ static void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x1f, 0x0004); rtl_writephy(tp, 0x1f, 0x0007); rtl_writephy(tp, 0x1e, 0x0020); - rtl_w1w0_phy(tp, 0x06, 0x0000, 0x0100); + rtl_w1w0_phy(tp, 0x15, 0x0000, 0x0100); rtl_writephy(tp, 0x1f, 0x0002); rtl_writephy(tp, 0x1f, 0x0000); rtl_writephy(tp, 0x0d, 0x0007); -- cgit v1.2.3 From afaef734e5f0004916d07ecf7d86292cdd00d59b Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Mon, 17 Oct 2011 15:20:28 +0000 Subject: fib_rules: fix unresolved_rules counting we should decrease ops->unresolved_rules when deleting a unresolved rule. Signed-off-by: Zheng Yan Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/fib_rules.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 3231b468bb7..27071ee2a4e 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -475,8 +475,11 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) list_del_rcu(&rule->list); - if (rule->action == FR_ACT_GOTO) + if (rule->action == FR_ACT_GOTO) { ops->nr_goto_rules--; + if (rtnl_dereference(rule->ctarget) == NULL) + ops->unresolved_rules--; + } /* * Check if this rule is a target to any of them. If so, -- cgit v1.2.3 From aad4564498dcb0aad769a79e5e2aa9a661dfb51f Mon Sep 17 00:00:00 2001 From: Kjetil Oftedal Date: Wed, 19 Oct 2011 16:20:50 -0700 Subject: sparc: Add alignment flag to PCI expansion resources Currently no type of alignment is specified for PCI expansion roms while parsing the openfirmware tree. This causes calls to pci_map_rom() to fail. IORESOURCE_SIZEALIGN is the default alignment used for rom resouces in pci/probe.c, and has been verified to work with various cards on a ultra 10. Signed-off-By: Kjetil Oftedal Signed-off-by: David S. Miller --- arch/sparc/kernel/pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 1e94f946570..8aa0d440858 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -230,7 +230,8 @@ static void pci_parse_of_addrs(struct platform_device *op, res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2]; } else if (i == dev->rom_base_reg) { res = &dev->resource[PCI_ROM_RESOURCE]; - flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE; + flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE + | IORESOURCE_SIZEALIGN; } else { printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i); continue; -- cgit v1.2.3 From 486cf46f3f9be5f2a966016c1a8fe01e32cde09e Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Wed, 19 Oct 2011 12:50:35 -0700 Subject: mm: fix race between mremap and removing migration entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I don't usually pay much attention to the stale "? " addresses in stack backtraces, but this lucky report from Pawel Sikora hints that mremap's move_ptes() has inadequate locking against page migration. 3.0 BUG_ON(!PageLocked(p)) in migration_entry_to_page(): kernel BUG at include/linux/swapops.h:105! RIP: 0010:[] [] migration_entry_wait+0x156/0x160 [] handle_pte_fault+0xae1/0xaf0 [] ? __pte_alloc+0x42/0x120 [] ? do_huge_pmd_anonymous_page+0xab/0x310 [] handle_mm_fault+0x181/0x310 [] ? vma_adjust+0x537/0x570 [] do_page_fault+0x11d/0x4e0 [] ? do_mremap+0x2d5/0x570 [] page_fault+0x1f/0x30 mremap's down_write of mmap_sem, together with i_mmap_mutex or lock, and pagetable locks, were good enough before page migration (with its requirement that every migration entry be found) came in, and enough while migration always held mmap_sem; but not enough nowadays, when there's memory hotremove and compaction. The danger is that move_ptes() lets a migration entry dodge around behind remove_migration_pte()'s back, so it's in the old location when looking at the new, then in the new location when looking at the old. Either mremap's move_ptes() must additionally take anon_vma lock(), or migration's remove_migration_pte() must stop peeking for is_swap_entry() before it takes pagetable lock. Consensus chooses the latter: we prefer to add overhead to migration than to mremapping, which gets used by JVMs and by exec stack setup. Reported-and-tested-by: Paweł Sikora Signed-off-by: Hugh Dickins Acked-by: Andrea Arcangeli Acked-by: Mel Gorman Cc: stable@vger.kernel.org Signed-off-by: Linus Torvalds --- mm/migrate.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mm/migrate.c b/mm/migrate.c index 666e4e67741..14d0a6a632f 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -120,10 +120,10 @@ static int remove_migration_pte(struct page *new, struct vm_area_struct *vma, ptep = pte_offset_map(pmd, addr); - if (!is_swap_pte(*ptep)) { - pte_unmap(ptep); - goto out; - } + /* + * Peek to check is_swap_pte() before taking ptlock? No, we + * can race mremap's move_ptes(), which skips anon_vma lock. + */ ptl = pte_lockptr(mm, pmd); } -- cgit v1.2.3 From 113ab386c7d6625cff284fb10952ff69a58c18a4 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 14 Oct 2011 04:57:46 +0000 Subject: ip_gre: dont increase dev->needed_headroom on a live device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It seems ip_gre is able to change dev->needed_headroom on the fly. Its is not legal unfortunately and triggers a BUG in raw_sendmsg() skb = sock_alloc_send_skb(sk, ... + LL_ALLOCATED_SPACE(rt->dst.dev) < another cpu change dev->needed_headromm (making it bigger) ... skb_reserve(skb, LL_RESERVED_SPACE(rt->dst.dev)); We end with LL_RESERVED_SPACE() being bigger than LL_ALLOCATED_SPACE() -> we crash later because skb head is exhausted. Bug introduced in commit 243aad83 in 2.6.34 (ip_gre: include route header_len in max_headroom calculation) Reported-by: Elmar Vonlanthen Signed-off-by: Eric Dumazet CC: Timo Teräs CC: Herbert Xu Signed-off-by: David S. Miller --- net/ipv4/ip_gre.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index d7bb94c4834..d55110e9312 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -835,8 +835,6 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev if (skb_headroom(skb) < max_headroom || skb_shared(skb)|| (skb_cloned(skb) && !skb_clone_writable(skb, 0))) { struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); - if (max_headroom > dev->needed_headroom) - dev->needed_headroom = max_headroom; if (!new_skb) { ip_rt_put(rt); dev->stats.tx_dropped++; -- cgit v1.2.3 From f7ff19871bb4a3451e1ca2cf660bf633018cfbec Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sat, 22 Oct 2011 03:29:53 -0400 Subject: tg3: fix tigon3_dma_hwbug_workaround() Ari got kernel panics using tg3 NIC, and bisected to 2669069aacc9 "tg3: enable transmit time stamping." This is because tigon3_dma_hwbug_workaround() might alloc a new skb and free the original. We panic when skb_tx_timestamp() is called on freed skb. Reported-by: Ari Savolainen Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/tg3.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index c11a2b8327f..d469004704a 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -6029,12 +6029,12 @@ static void tg3_tx_skb_unmap(struct tg3_napi *tnapi, u32 entry, int last) /* Workaround 4GB and 40-bit hardware DMA bugs. */ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi, - struct sk_buff *skb, + struct sk_buff **pskb, u32 *entry, u32 *budget, u32 base_flags, u32 mss, u32 vlan) { struct tg3 *tp = tnapi->tp; - struct sk_buff *new_skb; + struct sk_buff *new_skb, *skb = *pskb; dma_addr_t new_addr = 0; int ret = 0; @@ -6076,7 +6076,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi, } dev_kfree_skb(skb); - + *pskb = new_skb; return ret; } @@ -6305,7 +6305,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) */ entry = tnapi->tx_prod; budget = tg3_tx_avail(tnapi); - if (tigon3_dma_hwbug_workaround(tnapi, skb, &entry, &budget, + if (tigon3_dma_hwbug_workaround(tnapi, &skb, &entry, &budget, base_flags, mss, vlan)) goto out_unlock; } -- cgit v1.2.3 From da92b194cc36b5dc1fbd85206aeeffd80bee0c39 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Fri, 21 Oct 2011 00:49:15 +0000 Subject: net: hold sock reference while processing tx timestamps The pair of functions, * skb_clone_tx_timestamp() * skb_complete_tx_timestamp() were designed to allow timestamping in PHY devices. The first function, called during the MAC driver's hard_xmit method, identifies PTP protocol packets, clones them, and gives them to the PHY device driver. The PHY driver may hold onto the packet and deliver it at a later time using the second function, which adds the packet to the socket's error queue. As pointed out by Johannes, nothing prevents the socket from disappearing while the cloned packet is sitting in the PHY driver awaiting a timestamp. This patch fixes the issue by taking a reference on the socket for each such packet. In addition, the comments regarding the usage of these function are expanded to highlight the rule that PHY drivers must use skb_complete_tx_timestamp() to release the packet, in order to release the socket reference, too. These functions first appeared in v2.6.36. Reported-by: Johannes Berg Signed-off-by: Richard Cochran Cc: Signed-off-by: Eric Dumazet Reviewed-by: Johannes Berg Signed-off-by: David S. Miller --- include/linux/phy.h | 2 +- include/linux/skbuff.h | 7 ++++++- net/core/timestamping.c | 12 ++++++++++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/include/linux/phy.h b/include/linux/phy.h index 54fc4138955..79f337c4738 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -420,7 +420,7 @@ struct phy_driver { /* * Requests a Tx timestamp for 'skb'. The phy driver promises - * to deliver it to the socket's error queue as soon as a + * to deliver it using skb_complete_tx_timestamp() as soon as a * timestamp becomes available. One of the PTP_CLASS_ values * is passed in 'type'. */ diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 8bd383caa36..0f966460a34 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2020,8 +2020,13 @@ static inline bool skb_defer_rx_timestamp(struct sk_buff *skb) /** * skb_complete_tx_timestamp() - deliver cloned skb with tx timestamps * + * PHY drivers may accept clones of transmitted packets for + * timestamping via their phy_driver.txtstamp method. These drivers + * must call this function to return the skb back to the stack, with + * or without a timestamp. + * * @skb: clone of the the original outgoing packet - * @hwtstamps: hardware time stamps + * @hwtstamps: hardware time stamps, may be NULL if not available * */ void skb_complete_tx_timestamp(struct sk_buff *skb, diff --git a/net/core/timestamping.c b/net/core/timestamping.c index 98a52640e7c..82fb28857b6 100644 --- a/net/core/timestamping.c +++ b/net/core/timestamping.c @@ -57,9 +57,13 @@ void skb_clone_tx_timestamp(struct sk_buff *skb) case PTP_CLASS_V2_VLAN: phydev = skb->dev->phydev; if (likely(phydev->drv->txtstamp)) { + if (!atomic_inc_not_zero(&sk->sk_refcnt)) + return; clone = skb_clone(skb, GFP_ATOMIC); - if (!clone) + if (!clone) { + sock_put(sk); return; + } clone->sk = sk; phydev->drv->txtstamp(phydev, clone, type); } @@ -77,8 +81,11 @@ void skb_complete_tx_timestamp(struct sk_buff *skb, struct sock_exterr_skb *serr; int err; - if (!hwtstamps) + if (!hwtstamps) { + sock_put(sk); + kfree_skb(skb); return; + } *skb_hwtstamps(skb) = *hwtstamps; serr = SKB_EXT_ERR(skb); @@ -87,6 +94,7 @@ void skb_complete_tx_timestamp(struct sk_buff *skb, serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING; skb->sk = NULL; err = sock_queue_err_skb(sk, skb); + sock_put(sk); if (err) kfree_skb(skb); } -- cgit v1.2.3 From 7cc9150ebe8ec06cafea9f1c10d92ddacf88d8ae Mon Sep 17 00:00:00 2001 From: Flavio Leitner Date: Mon, 24 Oct 2011 02:56:38 -0400 Subject: route: fix ICMP redirect validation The commit f39925dbde7788cfb96419c0f092b086aa325c0f (ipv4: Cache learned redirect information in inetpeer.) removed some ICMP packet validations which are required by RFC 1122, section 3.2.2.2: ... A Redirect message SHOULD be silently discarded if the new gateway address it specifies is not on the same connected (sub-) net through which the Redirect arrived [INTRO:2, Appendix A], or if the source of the Redirect is not the current first-hop gateway for the specified destination (see Section 3.3.1). Signed-off-by: Flavio Leitner Signed-off-by: David S. Miller --- net/ipv4/route.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 075212e41b8..41557e2bb56 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1309,7 +1309,12 @@ static void rt_del(unsigned hash, struct rtable *rt) void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, __be32 saddr, struct net_device *dev) { + int s, i; struct in_device *in_dev = __in_dev_get_rcu(dev); + struct rtable *rt; + __be32 skeys[2] = { saddr, 0 }; + int ikeys[2] = { dev->ifindex, 0 }; + struct flowi4 fl4; struct inet_peer *peer; struct net *net; @@ -1332,13 +1337,34 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, goto reject_redirect; } - peer = inet_getpeer_v4(daddr, 1); - if (peer) { - peer->redirect_learned.a4 = new_gw; + memset(&fl4, 0, sizeof(fl4)); + fl4.daddr = daddr; + for (s = 0; s < 2; s++) { + for (i = 0; i < 2; i++) { + fl4.flowi4_oif = ikeys[i]; + fl4.saddr = skeys[s]; + rt = __ip_route_output_key(net, &fl4); + if (IS_ERR(rt)) + continue; - inet_putpeer(peer); + if (rt->dst.error || rt->dst.dev != dev || + rt->rt_gateway != old_gw) { + ip_rt_put(rt); + continue; + } - atomic_inc(&__rt_peer_genid); + if (!rt->peer) + rt_bind_peer(rt, rt->rt_dst, 1); + + peer = rt->peer; + if (peer) { + peer->redirect_learned.a4 = new_gw; + atomic_inc(&__rt_peer_genid); + } + + ip_rt_put(rt); + return; + } } return; -- cgit v1.2.3 From a7d5b76d9a7e434e32a5b2815db45489617dcba6 Mon Sep 17 00:00:00 2001 From: Clemens Buchacher Date: Sat, 22 Oct 2011 02:56:20 +0000 Subject: jme: fix irq storm after suspend/resume If the device is down during suspend/resume, interrupts are enabled without a registered interrupt handler, causing a storm of unhandled interrupts until the IRQ is disabled because "nobody cared". Instead, check that the device is up before touching it in the suspend/resume code. Fixes https://bugzilla.kernel.org/show_bug.cgi?id=39112 Helped-by: Adrian Chadd Helped-by: Mohammed Shafi Signed-off-by: Clemens Buchacher Signed-off-by: David S. Miller --- drivers/net/jme.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/jme.c b/drivers/net/jme.c index 3ac262f5563..7a8a3b64276 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -3131,6 +3131,9 @@ jme_suspend(struct device *dev) struct net_device *netdev = pci_get_drvdata(pdev); struct jme_adapter *jme = netdev_priv(netdev); + if (!netif_running(netdev)) + return 0; + atomic_dec(&jme->link_changing); netif_device_detach(netdev); @@ -3171,6 +3174,9 @@ jme_resume(struct device *dev) struct net_device *netdev = pci_get_drvdata(pdev); struct jme_adapter *jme = netdev_priv(netdev); + if (!netif_running(netdev)) + return 0; + jme_clear_pm(jme); jme_phy_on(jme); if (test_bit(JME_FLAG_SSET, &jme->flags)) -- cgit v1.2.3 From b73233960a59ee66e09d642f13d0592b13651e94 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Sat, 22 Oct 2011 21:58:20 +0000 Subject: ipv4: fix ipsec forward performance regression There is bug in commit 5e2b61f(ipv4: Remove flowi from struct rtable). It makes xfrm4_fill_dst() modify wrong data structure. Signed-off-by: Zheng Yan Reported-by: Kim Phillips Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/xfrm4_policy.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index fc5368ad2b0..a0b4c5da8d4 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -79,13 +79,13 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, struct rtable *rt = (struct rtable *)xdst->route; const struct flowi4 *fl4 = &fl->u.ip4; - rt->rt_key_dst = fl4->daddr; - rt->rt_key_src = fl4->saddr; - rt->rt_key_tos = fl4->flowi4_tos; - rt->rt_route_iif = fl4->flowi4_iif; - rt->rt_iif = fl4->flowi4_iif; - rt->rt_oif = fl4->flowi4_oif; - rt->rt_mark = fl4->flowi4_mark; + xdst->u.rt.rt_key_dst = fl4->daddr; + xdst->u.rt.rt_key_src = fl4->saddr; + xdst->u.rt.rt_key_tos = fl4->flowi4_tos; + xdst->u.rt.rt_route_iif = fl4->flowi4_iif; + xdst->u.rt.rt_iif = fl4->flowi4_iif; + xdst->u.rt.rt_oif = fl4->flowi4_oif; + xdst->u.rt.rt_mark = fl4->flowi4_mark; xdst->u.dst.dev = dev; dev_hold(dev); -- cgit v1.2.3 From d2237d35748e7f448a9c2d9dc6a85ef637466e24 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Fri, 21 Oct 2011 06:24:20 +0000 Subject: rtnetlink: Add missing manual netlink notification in dev_change_net_namespaces Renato Westphal noticed that since commit a2835763e130c343ace5320c20d33c281e7097b7 "rtnetlink: handle rtnl_link netlink notifications manually" was merged we no longer send a netlink message when a networking device is moved from one network namespace to another. Fix this by adding the missing manual notification in dev_change_net_namespaces. Since all network devices that are processed by dev_change_net_namspaces are in the initialized state the complicated tests that guard the manual rtmsg_ifinfo calls in rollback_registered and register_netdevice are unnecessary and we can just perform a plain notification. Cc: stable@kernel.org Tested-by: Renato Westphal Signed-off-by: Eric W. Biederman Signed-off-by: David S. Miller --- net/core/dev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/core/dev.c b/net/core/dev.c index b10ff0a7185..ae5cf2d630e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -6115,6 +6115,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char */ call_netdevice_notifiers(NETDEV_UNREGISTER, dev); call_netdevice_notifiers(NETDEV_UNREGISTER_BATCH, dev); + rtmsg_ifinfo(RTM_DELLINK, dev, ~0U); /* * Flush the unicast and multicast chains -- cgit v1.2.3 From f42af6c486aa5ca6ee62800cb45c5b252020509d Mon Sep 17 00:00:00 2001 From: Dirk Eibach Date: Tue, 18 Oct 2011 03:04:11 +0000 Subject: net: Fix driver name for mdio-gpio.c Since commit "7488876... dt/net: Eliminate users of of_platform_{,un}register_driver" there are two platform drivers named "mdio-gpio" registered. I renamed the of variant to "mdio-ofgpio". Signed-off-by: Dirk Eibach Signed-off-by: David S. Miller --- drivers/net/phy/mdio-gpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 47c8339a035..2843c90f712 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c @@ -241,7 +241,7 @@ MODULE_DEVICE_TABLE(of, mdio_ofgpio_match); static struct platform_driver mdio_ofgpio_driver = { .driver = { - .name = "mdio-gpio", + .name = "mdio-ofgpio", .owner = THIS_MODULE, .of_match_table = mdio_ofgpio_match, }, -- cgit v1.2.3