From: Greg Kroah-Hartman Date: Fri, 21 Jun 2013 15:39:09 +0000 (-0700) Subject: 3.9-stable patches X-Git-Tag: v3.0.84~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8067435cb858ab5f5b881d423dade170d1e605ad;p=thirdparty%2Fkernel%2Fstable-queue.git 3.9-stable patches added patches: parisc-add-kernel-stack-overflow-check.patch parisc-add-rp5470-entry-to-machine-database.patch parisc-fix-irq-stack-on-up-and-smp.patch parisc-fix-kernel-bug-at-arch-parisc-include-asm-mmzone.h-50-part-2.patch parisc-fix-kernel-bug-at-arch-parisc-include-asm-mmzone.h-50.patch parisc-fix-serial-ports-on-c8000-workstation.patch parisc-implement-irq-stacks-part-2-v2.patch parisc-implement-irq-stacks.patch parisc-kernel-using-strlcpy-instead-of-strcpy.patch parisc-make-interrupt-and-interruption-stack-allocation-reentrant.patch parisc-memory-overflow-name-length-is-too-short-for-using.patch parisc-more-irq-statistics-in-proc-interrupts.patch parisc-parport0-fix-this-legacy-no-device-port-driver.patch parisc-provide-pci_mmap_page_range-for-parisc.patch parisc-remove-the-second-argument-of-kmap_atomic.patch parisc-rename-config_pa7100-to-config_pa7000.patch parisc-show-number-of-fpe-and-unaligned-access-handler-calls-in-proc-interrupts.patch parisc-tlb-flush-counting-fix-for-smp-and-up.patch --- diff --git a/queue-3.9/parisc-add-kernel-stack-overflow-check.patch b/queue-3.9/parisc-add-kernel-stack-overflow-check.patch new file mode 100644 index 00000000000..5da00470d81 --- /dev/null +++ b/queue-3.9/parisc-add-kernel-stack-overflow-check.patch @@ -0,0 +1,125 @@ +From 9372450cc22d185f708e5cc3557cf991be4b7dc5 Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Tue, 7 May 2013 19:28:52 +0000 +Subject: parisc: add kernel stack overflow check + +From: Helge Deller + +commit 9372450cc22d185f708e5cc3557cf991be4b7dc5 upstream. + +Add the CONFIG_DEBUG_STACKOVERFLOW config option to enable checks to +detect kernel stack overflows. + +Stack overflows can not be detected reliable since we do not want to +introduce too much overhead. + +Instead, during irq processing in do_cpu_irq_mask() we check kernel +stack usage of the interrupted kernel process. Kernel threads can be +easily detected by checking the value of space register 7 (sr7) which +is zero when running inside the kernel. + +Since THREAD_SIZE is 16k and PAGE_SIZE is 4k, reduce the alignment of +the init thread to the lower value (PAGE_SIZE) in the kernel +vmlinux.ld.S linker script. + +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/Kconfig.debug | 11 +++++++++++ + arch/parisc/include/asm/thread_info.h | 2 +- + arch/parisc/kernel/irq.c | 31 +++++++++++++++++++++++++++++-- + arch/parisc/kernel/vmlinux.lds.S | 2 +- + 4 files changed, 42 insertions(+), 4 deletions(-) + +--- a/arch/parisc/Kconfig.debug ++++ b/arch/parisc/Kconfig.debug +@@ -27,3 +27,14 @@ config DEBUG_STRICT_USER_COPY_CHECKS + If unsure, or if you run an older (pre 4.4) gcc, say N. + + endmenu ++ ++config DEBUG_STACKOVERFLOW ++ bool "Check for stack overflows" ++ default y ++ depends on DEBUG_KERNEL ++ ---help--- ++ Say Y here if you want to check the overflows of kernel, IRQ ++ and exception stacks. This option will cause messages of the ++ stacks in detail when free stack space drops below a certain ++ limit. ++ If in doubt, say "N". +--- a/arch/parisc/include/asm/thread_info.h ++++ b/arch/parisc/include/asm/thread_info.h +@@ -40,7 +40,7 @@ struct thread_info { + + /* thread information allocation */ + +-#define THREAD_SIZE_ORDER 2 ++#define THREAD_SIZE_ORDER 2 /* PA-RISC requires at least 16k stack */ + /* Be sure to hunt all references to this down when you change the size of + * the kernel stack */ + #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) +--- a/arch/parisc/kernel/irq.c ++++ b/arch/parisc/kernel/irq.c +@@ -330,6 +330,34 @@ static inline int eirr_to_irq(unsigned l + return (BITS_PER_LONG - bit) + TIMER_IRQ; + } + ++int sysctl_panic_on_stackoverflow = 1; ++ ++static inline void stack_overflow_check(struct pt_regs *regs) ++{ ++#ifdef CONFIG_DEBUG_STACKOVERFLOW ++ #define STACK_MARGIN (256*6) ++ ++ /* Our stack starts directly behind the thread_info struct. */ ++ unsigned long stack_start = (unsigned long) current_thread_info(); ++ unsigned long sp = regs->gr[30]; ++ ++ /* if sr7 != 0, we interrupted a userspace process which we do not want ++ * to check for stack overflow. We will only check the kernel stack. */ ++ if (regs->sr[7]) ++ return; ++ ++ if (likely((sp - stack_start) < (THREAD_SIZE - STACK_MARGIN))) ++ return; ++ ++ pr_emerg("stackcheck: %s will most likely overflow kernel stack " ++ "(sp:%lx, stk bottom-top:%lx-%lx)\n", ++ current->comm, sp, stack_start, stack_start + THREAD_SIZE); ++ ++ if (sysctl_panic_on_stackoverflow) ++ panic("low stack detected by irq handler - check messages\n"); ++#endif ++} ++ + /* ONLY called from entry.S:intr_extint() */ + void do_cpu_irq_mask(struct pt_regs *regs) + { +@@ -364,6 +392,7 @@ void do_cpu_irq_mask(struct pt_regs *reg + goto set_out; + } + #endif ++ stack_overflow_check(regs); + generic_handle_irq(irq); + + out: +@@ -420,6 +449,4 @@ void __init init_IRQ(void) + cpu_eiem = EIEM_MASK(TIMER_IRQ); + #endif + set_eiem(cpu_eiem); /* EIEM : enable all external intr */ +- + } +- +--- a/arch/parisc/kernel/vmlinux.lds.S ++++ b/arch/parisc/kernel/vmlinux.lds.S +@@ -95,7 +95,7 @@ SECTIONS + NOTES + + /* Data */ +- RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE) ++ RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, PAGE_SIZE) + + /* PA-RISC locks requires 16-byte alignment */ + . = ALIGN(16); diff --git a/queue-3.9/parisc-add-rp5470-entry-to-machine-database.patch b/queue-3.9/parisc-add-rp5470-entry-to-machine-database.patch new file mode 100644 index 00000000000..730555623ad --- /dev/null +++ b/queue-3.9/parisc-add-rp5470-entry-to-machine-database.patch @@ -0,0 +1,26 @@ +From 949451b9b19da5e998778eb78929aafc73b5c227 Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Thu, 16 May 2013 20:42:39 +0000 +Subject: parisc: add rp5470 entry to machine database + +From: Helge Deller + +commit 949451b9b19da5e998778eb78929aafc73b5c227 upstream. + +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/kernel/hardware.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/parisc/kernel/hardware.c ++++ b/arch/parisc/kernel/hardware.c +@@ -222,6 +222,7 @@ static struct hp_hardware hp_hardware_li + {HPHW_NPROC,0x5DD,0x4,0x81,"Duet W2"}, + {HPHW_NPROC,0x5DE,0x4,0x81,"Piccolo W+"}, + {HPHW_NPROC,0x5DF,0x4,0x81,"Cantata W2"}, ++ {HPHW_NPROC,0x5DF,0x0,0x00,"Marcato W+? (rp5470)"}, + {HPHW_NPROC,0x5E0,0x4,0x91,"Cantata DC- W2"}, + {HPHW_NPROC,0x5E1,0x4,0x91,"Crescendo DC- W2"}, + {HPHW_NPROC,0x5E2,0x4,0x91,"Crescendo 650 W2"}, diff --git a/queue-3.9/parisc-fix-irq-stack-on-up-and-smp.patch b/queue-3.9/parisc-fix-irq-stack-on-up-and-smp.patch new file mode 100644 index 00000000000..25e7a23c82a --- /dev/null +++ b/queue-3.9/parisc-fix-irq-stack-on-up-and-smp.patch @@ -0,0 +1,181 @@ +From d96b51ec14650b490ab98e738bcc02309396e5bc Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Fri, 24 May 2013 21:27:35 +0000 +Subject: parisc: fix irq stack on UP and SMP + +From: Helge Deller + +commit d96b51ec14650b490ab98e738bcc02309396e5bc upstream. + +The logic to detect if the irq stack was already in use with +raw_spin_trylock() is wrong, because it will generate a "trylock failure +on UP" error message with CONFIG_SMP=n and CONFIG_DEBUG_SPINLOCK=y. + +arch_spin_trylock() can't be used either since in the CONFIG_SMP=n case +no atomic protection is given and we are reentrant here. A mutex didn't +worked either and brings more overhead by turning off interrupts. + +So, let's use the fastest path for parisc which is the ldcw instruction. + +Counting how often the irq stack was used is pretty useless, so just +drop this piece of code. + +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/include/asm/hardirq.h | 5 ---- + arch/parisc/include/asm/processor.h | 21 ------------------ + arch/parisc/kernel/irq.c | 41 ++++++++++++++++++++++-------------- + 3 files changed, 26 insertions(+), 41 deletions(-) + +--- a/arch/parisc/include/asm/hardirq.h ++++ b/arch/parisc/include/asm/hardirq.h +@@ -17,13 +17,8 @@ + + typedef struct { + unsigned int __softirq_pending; +-#ifdef CONFIG_DEBUG_STACKOVERFLOW + unsigned int kernel_stack_usage; +-#ifdef CONFIG_IRQSTACKS + unsigned int irq_stack_usage; +- unsigned int irq_stack_counter; +-#endif +-#endif + #ifdef CONFIG_SMP + unsigned int irq_resched_count; + unsigned int irq_call_count; +--- a/arch/parisc/include/asm/processor.h ++++ b/arch/parisc/include/asm/processor.h +@@ -17,7 +17,6 @@ + #include + #include + #include +- + #endif /* __ASSEMBLY__ */ + + /* +@@ -59,26 +58,6 @@ + #ifndef __ASSEMBLY__ + + /* +- * IRQ STACK - used for irq handler +- */ +-#ifdef __KERNEL__ +- +-#include +- +-#define IRQ_STACK_SIZE (4096 << 2) /* 16k irq stack size */ +- +-union irq_stack_union { +- unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)]; +- raw_spinlock_t lock; +-}; +- +-DECLARE_PER_CPU(union irq_stack_union, irq_stack_union); +- +-void call_on_stack(unsigned long p1, void *func, unsigned long new_stack); +- +-#endif /* __KERNEL__ */ +- +-/* + * Data detected about CPUs at boot time which is the same for all CPU's. + * HP boxes are SMP - ie identical processors. + * +--- a/arch/parisc/kernel/irq.c ++++ b/arch/parisc/kernel/irq.c +@@ -27,11 +27,11 @@ + #include + #include + #include +-#include + #include + #include + + #include ++#include + + #undef PARISC_IRQ_CR16_COUNTS + +@@ -172,10 +172,6 @@ int arch_show_interrupts(struct seq_file + for_each_online_cpu(j) + seq_printf(p, "%10u ", irq_stats(j)->irq_stack_usage); + seq_puts(p, " Interrupt stack usage\n"); +- seq_printf(p, "%*s: ", prec, "ISC"); +- for_each_online_cpu(j) +- seq_printf(p, "%10u ", irq_stats(j)->irq_stack_counter); +- seq_puts(p, " Interrupt stack usage counter\n"); + # endif + #endif + #ifdef CONFIG_SMP +@@ -384,6 +380,24 @@ static inline int eirr_to_irq(unsigned l + return (BITS_PER_LONG - bit) + TIMER_IRQ; + } + ++#ifdef CONFIG_IRQSTACKS ++/* ++ * IRQ STACK - used for irq handler ++ */ ++#define IRQ_STACK_SIZE (4096 << 2) /* 16k irq stack size */ ++ ++union irq_stack_union { ++ unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)]; ++ volatile unsigned int slock[4]; ++ volatile unsigned int lock[1]; ++}; ++ ++DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = { ++ .slock = { 1,1,1,1 }, ++ }; ++#endif ++ ++ + int sysctl_panic_on_stackoverflow = 1; + + static inline void stack_overflow_check(struct pt_regs *regs) +@@ -450,27 +464,26 @@ panic_check: + } + + #ifdef CONFIG_IRQSTACKS +-DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = { +- .lock = __RAW_SPIN_LOCK_UNLOCKED((irq_stack_union).lock) +- }; ++/* in entry.S: */ ++void call_on_stack(unsigned long p1, void *func, unsigned long new_stack); + + static void execute_on_irq_stack(void *func, unsigned long param1) + { + union irq_stack_union *union_ptr; + unsigned long irq_stack; +- raw_spinlock_t *irq_stack_in_use; ++ volatile unsigned int *irq_stack_in_use; + + union_ptr = &per_cpu(irq_stack_union, smp_processor_id()); + irq_stack = (unsigned long) &union_ptr->stack; +- irq_stack = ALIGN(irq_stack + sizeof(irq_stack_union.lock), ++ irq_stack = ALIGN(irq_stack + sizeof(irq_stack_union.slock), + 64); /* align for stack frame usage */ + + /* We may be called recursive. If we are already using the irq stack, + * just continue to use it. Use spinlocks to serialize + * the irq stack usage. + */ +- irq_stack_in_use = &union_ptr->lock; +- if (!raw_spin_trylock(irq_stack_in_use)) { ++ irq_stack_in_use = (volatile unsigned int *)__ldcw_align(union_ptr); ++ if (!__ldcw(irq_stack_in_use)) { + void (*direct_call)(unsigned long p1) = func; + + /* We are using the IRQ stack already. +@@ -482,10 +495,8 @@ static void execute_on_irq_stack(void *f + /* This is where we switch to the IRQ stack. */ + call_on_stack(param1, func, irq_stack); + +- __inc_irq_stat(irq_stack_counter); +- + /* free up irq stack usage. */ +- do_raw_spin_unlock(irq_stack_in_use); ++ *irq_stack_in_use = 1; + } + + asmlinkage void do_softirq(void) diff --git a/queue-3.9/parisc-fix-kernel-bug-at-arch-parisc-include-asm-mmzone.h-50-part-2.patch b/queue-3.9/parisc-fix-kernel-bug-at-arch-parisc-include-asm-mmzone.h-50-part-2.patch new file mode 100644 index 00000000000..e2a4132db6b --- /dev/null +++ b/queue-3.9/parisc-fix-kernel-bug-at-arch-parisc-include-asm-mmzone.h-50-part-2.patch @@ -0,0 +1,58 @@ +From 91ea8207168793b365322be3c90a4ee9e8b03ed4 Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Wed, 5 Jun 2013 20:50:01 +0000 +Subject: parisc: fix kernel BUG at arch/parisc/include/asm/mmzone.h:50 (part 2) + +From: Helge Deller + +commit 91ea8207168793b365322be3c90a4ee9e8b03ed4 upstream. + +Make sure that we really return -1 (instead of 0x00ff) as node id for +page frame numbers which are not physically available. + +This finally fixes the kernel panic when running +cat /proc/kpageflags /proc/kpagecount. + +Theoretically this patch now limits the number of physical memory ranges +to 127 instead of 254, but currently we have MAX_PHYSMEM_RANGES +hardcoded to 8 which is sufficient for all existing parisc machines. + +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/include/asm/mmzone.h | 4 ++-- + arch/parisc/mm/init.c | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/parisc/include/asm/mmzone.h ++++ b/arch/parisc/include/asm/mmzone.h +@@ -27,7 +27,7 @@ extern struct node_map_data node_data[]; + + #define PFNNID_SHIFT (30 - PAGE_SHIFT) + #define PFNNID_MAP_MAX 512 /* support 512GB */ +-extern unsigned char pfnnid_map[PFNNID_MAP_MAX]; ++extern signed char pfnnid_map[PFNNID_MAP_MAX]; + + #ifndef CONFIG_64BIT + #define pfn_is_io(pfn) ((pfn & (0xf0000000UL >> PAGE_SHIFT)) == (0xf0000000UL >> PAGE_SHIFT)) +@@ -46,7 +46,7 @@ static inline int pfn_to_nid(unsigned lo + i = pfn >> PFNNID_SHIFT; + BUG_ON(i >= ARRAY_SIZE(pfnnid_map)); + +- return (int)pfnnid_map[i]; ++ return pfnnid_map[i]; + } + + static inline int pfn_valid(int pfn) +--- a/arch/parisc/mm/init.c ++++ b/arch/parisc/mm/init.c +@@ -47,7 +47,7 @@ pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __a + + #ifdef CONFIG_DISCONTIGMEM + struct node_map_data node_data[MAX_NUMNODES] __read_mostly; +-unsigned char pfnnid_map[PFNNID_MAP_MAX] __read_mostly; ++signed char pfnnid_map[PFNNID_MAP_MAX] __read_mostly; + #endif + + static struct resource data_resource = { diff --git a/queue-3.9/parisc-fix-kernel-bug-at-arch-parisc-include-asm-mmzone.h-50.patch b/queue-3.9/parisc-fix-kernel-bug-at-arch-parisc-include-asm-mmzone.h-50.patch new file mode 100644 index 00000000000..aa947098d28 --- /dev/null +++ b/queue-3.9/parisc-fix-kernel-bug-at-arch-parisc-include-asm-mmzone.h-50.patch @@ -0,0 +1,56 @@ +From ae249b5fa27f9fba25aa59664d4338efc2dd2394 Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Tue, 28 May 2013 20:35:54 +0000 +Subject: parisc: fix kernel BUG at arch/parisc/include/asm/mmzone.h:50 + +From: Helge Deller + +commit ae249b5fa27f9fba25aa59664d4338efc2dd2394 upstream. + +With CONFIG_DISCONTIGMEM=y and multiple physical memory areas, +cat /proc/kpageflags triggers this kernel bug: + +kernel BUG at arch/parisc/include/asm/mmzone.h:50! +CPU: 2 PID: 7848 Comm: cat Tainted: G D W 3.10.0-rc3-64bit #44 + IAOQ[0]: kpageflags_read0x128/0x238 + IAOQ[1]: kpageflags_read0x12c/0x238 + RP(r2): proc_reg_read0xbc/0x130 +Backtrace: + [<00000000402ca2d4>] proc_reg_read0xbc/0x130 + [<0000000040235bcc>] vfs_read0xc4/0x1d0 + [<0000000040235f0c>] SyS_read0x94/0xf0 + [<0000000040105fc0>] syscall_exit0x0/0x14 + +kpageflags_read() walks through the whole memory, even if some memory +areas are physically not available. So, we should better not BUG on an +unavailable pfn in pfn_to_nid() but just return the expected value -1 or +0. + +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/include/asm/mmzone.h | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +--- a/arch/parisc/include/asm/mmzone.h ++++ b/arch/parisc/include/asm/mmzone.h +@@ -39,17 +39,14 @@ extern unsigned char pfnnid_map[PFNNID_M + static inline int pfn_to_nid(unsigned long pfn) + { + unsigned int i; +- unsigned char r; + + if (unlikely(pfn_is_io(pfn))) + return 0; + + i = pfn >> PFNNID_SHIFT; + BUG_ON(i >= ARRAY_SIZE(pfnnid_map)); +- r = pfnnid_map[i]; +- BUG_ON(r == 0xff); + +- return (int)r; ++ return (int)pfnnid_map[i]; + } + + static inline int pfn_valid(int pfn) diff --git a/queue-3.9/parisc-fix-serial-ports-on-c8000-workstation.patch b/queue-3.9/parisc-fix-serial-ports-on-c8000-workstation.patch new file mode 100644 index 00000000000..ef92f8c0521 --- /dev/null +++ b/queue-3.9/parisc-fix-serial-ports-on-c8000-workstation.patch @@ -0,0 +1,149 @@ +From 9a66d1869d90f13fbaf83dcce5b1aeec86fbc699 Mon Sep 17 00:00:00 2001 +From: Thomas Bogendoerfer +Date: Sun, 9 Jun 2013 23:00:21 +0200 +Subject: parisc: fix serial ports on C8000 workstation + +From: Thomas Bogendoerfer + +commit 9a66d1869d90f13fbaf83dcce5b1aeec86fbc699 upstream. + +The C8000 workstation (64 bit kernel only) has a somewhat different +serial port configuration than other models. +Thomas Bogendoerfer sent a patch to fix this in September 2010, which +was now minimally modified by me. + +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/kernel/hardware.c | 1 + drivers/parisc/iosapic.c | 66 +++++++++++++++++++++++++++++++++++++ + drivers/tty/serial/8250/8250_gsc.c | 10 +++++ + 3 files changed, 76 insertions(+), 1 deletion(-) + +--- a/arch/parisc/kernel/hardware.c ++++ b/arch/parisc/kernel/hardware.c +@@ -1205,6 +1205,7 @@ static struct hp_hardware hp_hardware_li + {HPHW_FIO, 0x004, 0x00320, 0x0, "Metheus Frame Buffer"}, + {HPHW_FIO, 0x004, 0x00340, 0x0, "BARCO CX4500 VME Grphx Cnsl"}, + {HPHW_FIO, 0x004, 0x00360, 0x0, "Hughes TOG VME FDDI"}, ++ {HPHW_FIO, 0x076, 0x000AD, 0x00, "Crestone Peak RS-232"}, + {HPHW_IOA, 0x185, 0x0000B, 0x00, "Java BC Summit Port"}, + {HPHW_IOA, 0x1FF, 0x0000B, 0x00, "Hitachi Ghostview Summit Port"}, + {HPHW_IOA, 0x580, 0x0000B, 0x10, "U2-IOA BC Runway Port"}, +--- a/drivers/parisc/iosapic.c ++++ b/drivers/parisc/iosapic.c +@@ -811,6 +811,70 @@ int iosapic_fixup_irq(void *isi_obj, str + return pcidev->irq; + } + ++static struct iosapic_info *first_isi = NULL; ++ ++#ifdef CONFIG_64BIT ++int iosapic_serial_irq(int num) ++{ ++ struct iosapic_info *isi = first_isi; ++ struct irt_entry *irte = NULL; /* only used if PAT PDC */ ++ struct vector_info *vi; ++ int isi_line; /* line used by device */ ++ ++ /* lookup IRT entry for isi/slot/pin set */ ++ irte = &irt_cell[num]; ++ ++ DBG_IRT("iosapic_serial_irq(): irte %p %x %x %x %x %x %x %x %x\n", ++ irte, ++ irte->entry_type, ++ irte->entry_length, ++ irte->polarity_trigger, ++ irte->src_bus_irq_devno, ++ irte->src_bus_id, ++ irte->src_seg_id, ++ irte->dest_iosapic_intin, ++ (u32) irte->dest_iosapic_addr); ++ isi_line = irte->dest_iosapic_intin; ++ ++ /* get vector info for this input line */ ++ vi = isi->isi_vector + isi_line; ++ DBG_IRT("iosapic_serial_irq: line %d vi 0x%p\n", isi_line, vi); ++ ++ /* If this IRQ line has already been setup, skip it */ ++ if (vi->irte) ++ goto out; ++ ++ vi->irte = irte; ++ ++ /* ++ * Allocate processor IRQ ++ * ++ * XXX/FIXME The txn_alloc_irq() code and related code should be ++ * moved to enable_irq(). That way we only allocate processor IRQ ++ * bits for devices that actually have drivers claiming them. ++ * Right now we assign an IRQ to every PCI device present, ++ * regardless of whether it's used or not. ++ */ ++ vi->txn_irq = txn_alloc_irq(8); ++ ++ if (vi->txn_irq < 0) ++ panic("I/O sapic: couldn't get TXN IRQ\n"); ++ ++ /* enable_irq() will use txn_* to program IRdT */ ++ vi->txn_addr = txn_alloc_addr(vi->txn_irq); ++ vi->txn_data = txn_alloc_data(vi->txn_irq); ++ ++ vi->eoi_addr = isi->addr + IOSAPIC_REG_EOI; ++ vi->eoi_data = cpu_to_le32(vi->txn_data); ++ ++ cpu_claim_irq(vi->txn_irq, &iosapic_interrupt_type, vi); ++ ++ out: ++ ++ return vi->txn_irq; ++} ++#endif ++ + + /* + ** squirrel away the I/O Sapic Version +@@ -877,6 +941,8 @@ void *iosapic_register(unsigned long hpa + vip->irqline = (unsigned char) cnt; + vip->iosapic = isi; + } ++ if (!first_isi) ++ first_isi = isi; + return isi; + } + +--- a/drivers/tty/serial/8250/8250_gsc.c ++++ b/drivers/tty/serial/8250/8250_gsc.c +@@ -30,6 +30,12 @@ static int __init serial_init_chip(struc + unsigned long address; + int err; + ++#ifdef CONFIG_64BIT ++ extern int iosapic_serial_irq(int cellnum); ++ if (!dev->irq && (dev->id.sversion == 0xad)) ++ dev->irq = iosapic_serial_irq(dev->mod_index-1); ++#endif ++ + if (!dev->irq) { + /* We find some unattached serial ports by walking native + * busses. These should be silently ignored. Otherwise, +@@ -51,7 +57,8 @@ static int __init serial_init_chip(struc + memset(&uart, 0, sizeof(uart)); + uart.port.iotype = UPIO_MEM; + /* 7.272727MHz on Lasi. Assumed the same for Dino, Wax and Timi. */ +- uart.port.uartclk = 7272727; ++ uart.port.uartclk = (dev->id.sversion != 0xad) ? ++ 7272727 : 1843200; + uart.port.mapbase = address; + uart.port.membase = ioremap_nocache(address, 16); + uart.port.irq = dev->irq; +@@ -73,6 +80,7 @@ static struct parisc_device_id serial_tb + { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00075 }, + { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008c }, + { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008d }, ++ { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x000ad }, + { 0 } + }; + diff --git a/queue-3.9/parisc-implement-irq-stacks-part-2-v2.patch b/queue-3.9/parisc-implement-irq-stacks-part-2-v2.patch new file mode 100644 index 00000000000..c7d07de9cc9 --- /dev/null +++ b/queue-3.9/parisc-implement-irq-stacks-part-2-v2.patch @@ -0,0 +1,269 @@ +From 416821d3d68164909b2cbcf398e4ba0797f5f8a2 Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Fri, 10 May 2013 21:24:01 +0000 +Subject: parisc: implement irq stacks - part 2 (v2) + +From: Helge Deller + +commit 416821d3d68164909b2cbcf398e4ba0797f5f8a2 upstream. + +This patch fixes few build issues which were introduced with the last +irq stack patch, e.g. the combination of stack overflow check and irq +stack. + +Furthermore we now do proper locking and change the irq bh handler +to use the irq stack as well. + +In /proc/interrupts one now can monitor how huge the irq stack has grown +and how often it was preferred over the kernel stack. + +IRQ stacks are now enabled by default just to make sure that we not +overflow the kernel stack by accident. + +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/Kconfig | 2 + arch/parisc/include/asm/hardirq.h | 9 +++ + arch/parisc/include/asm/processor.h | 3 + + arch/parisc/kernel/irq.c | 103 ++++++++++++++++++++++++++++++------ + arch/parisc/mm/init.c | 4 - + 5 files changed, 103 insertions(+), 18 deletions(-) + +--- a/arch/parisc/Kconfig ++++ b/arch/parisc/Kconfig +@@ -243,7 +243,7 @@ config SMP + + config IRQSTACKS + bool "Use separate kernel stacks when processing interrupts" +- default n ++ default y + help + If you say Y here the kernel will use separate kernel stacks + for handling hard and soft interrupts. This can help avoid +--- a/arch/parisc/include/asm/hardirq.h ++++ b/arch/parisc/include/asm/hardirq.h +@@ -11,10 +11,18 @@ + #include + #include + ++#ifdef CONFIG_IRQSTACKS ++#define __ARCH_HAS_DO_SOFTIRQ ++#endif ++ + typedef struct { + unsigned int __softirq_pending; + #ifdef CONFIG_DEBUG_STACKOVERFLOW + unsigned int kernel_stack_usage; ++#ifdef CONFIG_IRQSTACKS ++ unsigned int irq_stack_usage; ++ unsigned int irq_stack_counter; ++#endif + #endif + #ifdef CONFIG_SMP + unsigned int irq_resched_count; +@@ -28,6 +36,7 @@ DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpust + #define __ARCH_IRQ_STAT + #define __IRQ_STAT(cpu, member) (irq_stat[cpu].member) + #define inc_irq_stat(member) this_cpu_inc(irq_stat.member) ++#define __inc_irq_stat(member) __this_cpu_inc(irq_stat.member) + #define local_softirq_pending() this_cpu_read(irq_stat.__softirq_pending) + + #define __ARCH_SET_SOFTIRQ_PENDING +--- a/arch/parisc/include/asm/processor.h ++++ b/arch/parisc/include/asm/processor.h +@@ -63,10 +63,13 @@ + */ + #ifdef __KERNEL__ + ++#include ++ + #define IRQ_STACK_SIZE (4096 << 2) /* 16k irq stack size */ + + union irq_stack_union { + unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)]; ++ raw_spinlock_t lock; + }; + + DECLARE_PER_CPU(union irq_stack_union, irq_stack_union); +--- a/arch/parisc/kernel/irq.c ++++ b/arch/parisc/kernel/irq.c +@@ -166,22 +166,32 @@ int arch_show_interrupts(struct seq_file + seq_printf(p, "%*s: ", prec, "STK"); + for_each_online_cpu(j) + seq_printf(p, "%10u ", irq_stats(j)->kernel_stack_usage); +- seq_printf(p, " Kernel stack usage\n"); ++ seq_puts(p, " Kernel stack usage\n"); ++# ifdef CONFIG_IRQSTACKS ++ seq_printf(p, "%*s: ", prec, "IST"); ++ for_each_online_cpu(j) ++ seq_printf(p, "%10u ", irq_stats(j)->irq_stack_usage); ++ seq_puts(p, " Interrupt stack usage\n"); ++ seq_printf(p, "%*s: ", prec, "ISC"); ++ for_each_online_cpu(j) ++ seq_printf(p, "%10u ", irq_stats(j)->irq_stack_counter); ++ seq_puts(p, " Interrupt stack usage counter\n"); ++# endif + #endif + #ifdef CONFIG_SMP + seq_printf(p, "%*s: ", prec, "RES"); + for_each_online_cpu(j) + seq_printf(p, "%10u ", irq_stats(j)->irq_resched_count); +- seq_printf(p, " Rescheduling interrupts\n"); ++ seq_puts(p, " Rescheduling interrupts\n"); + seq_printf(p, "%*s: ", prec, "CAL"); + for_each_online_cpu(j) + seq_printf(p, "%10u ", irq_stats(j)->irq_call_count); +- seq_printf(p, " Function call interrupts\n"); ++ seq_puts(p, " Function call interrupts\n"); + #endif + seq_printf(p, "%*s: ", prec, "TLB"); + for_each_online_cpu(j) + seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count); +- seq_printf(p, " TLB shootdowns\n"); ++ seq_puts(p, " TLB shootdowns\n"); + return 0; + } + +@@ -378,6 +388,7 @@ static inline void stack_overflow_check( + unsigned long sp = regs->gr[30]; + unsigned long stack_usage; + unsigned int *last_usage; ++ int cpu = smp_processor_id(); + + /* if sr7 != 0, we interrupted a userspace process which we do not want + * to check for stack overflow. We will only check the kernel stack. */ +@@ -386,7 +397,31 @@ static inline void stack_overflow_check( + + /* calculate kernel stack usage */ + stack_usage = sp - stack_start; +- last_usage = &per_cpu(irq_stat.kernel_stack_usage, smp_processor_id()); ++#ifdef CONFIG_IRQSTACKS ++ if (likely(stack_usage <= THREAD_SIZE)) ++ goto check_kernel_stack; /* found kernel stack */ ++ ++ /* check irq stack usage */ ++ stack_start = (unsigned long) &per_cpu(irq_stack_union, cpu).stack; ++ stack_usage = sp - stack_start; ++ ++ last_usage = &per_cpu(irq_stat.irq_stack_usage, cpu); ++ if (unlikely(stack_usage > *last_usage)) ++ *last_usage = stack_usage; ++ ++ if (likely(stack_usage < (IRQ_STACK_SIZE - STACK_MARGIN))) ++ return; ++ ++ pr_emerg("stackcheck: %s will most likely overflow irq stack " ++ "(sp:%lx, stk bottom-top:%lx-%lx)\n", ++ current->comm, sp, stack_start, stack_start + IRQ_STACK_SIZE); ++ goto panic_check; ++ ++check_kernel_stack: ++#endif ++ ++ /* check kernel stack usage */ ++ last_usage = &per_cpu(irq_stat.kernel_stack_usage, cpu); + + if (unlikely(stack_usage > *last_usage)) + *last_usage = stack_usage; +@@ -398,31 +433,69 @@ static inline void stack_overflow_check( + "(sp:%lx, stk bottom-top:%lx-%lx)\n", + current->comm, sp, stack_start, stack_start + THREAD_SIZE); + ++#ifdef CONFIG_IRQSTACKS ++panic_check: ++#endif + if (sysctl_panic_on_stackoverflow) + panic("low stack detected by irq handler - check messages\n"); + #endif + } + + #ifdef CONFIG_IRQSTACKS +-DEFINE_PER_CPU(union irq_stack_union, irq_stack_union); ++DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = { ++ .lock = __RAW_SPIN_LOCK_UNLOCKED((irq_stack_union).lock) ++ }; + + static void execute_on_irq_stack(void *func, unsigned long param1) + { +- unsigned long *irq_stack_start; ++ union irq_stack_union *union_ptr; + unsigned long irq_stack; +- int cpu = smp_processor_id(); ++ raw_spinlock_t *irq_stack_in_use; + +- irq_stack_start = &per_cpu(irq_stack_union, cpu).stack[0]; +- irq_stack = (unsigned long) irq_stack_start; +- irq_stack = ALIGN(irq_stack, 16); /* align for stack frame usage */ +- +- BUG_ON(*irq_stack_start); /* report bug if we were called recursive. */ +- *irq_stack_start = 1; ++ union_ptr = &per_cpu(irq_stack_union, smp_processor_id()); ++ irq_stack = (unsigned long) &union_ptr->stack; ++ irq_stack = ALIGN(irq_stack + sizeof(irq_stack_union.lock), ++ 64); /* align for stack frame usage */ ++ ++ /* We may be called recursive. If we are already using the irq stack, ++ * just continue to use it. Use spinlocks to serialize ++ * the irq stack usage. ++ */ ++ irq_stack_in_use = &union_ptr->lock; ++ if (!raw_spin_trylock(irq_stack_in_use)) { ++ void (*direct_call)(unsigned long p1) = func; ++ ++ /* We are using the IRQ stack already. ++ * Do direct call on current stack. */ ++ direct_call(param1); ++ return; ++ } + + /* This is where we switch to the IRQ stack. */ + call_on_stack(param1, func, irq_stack); + +- *irq_stack_start = 0; ++ __inc_irq_stat(irq_stack_counter); ++ ++ /* free up irq stack usage. */ ++ do_raw_spin_unlock(irq_stack_in_use); ++} ++ ++asmlinkage void do_softirq(void) ++{ ++ __u32 pending; ++ unsigned long flags; ++ ++ if (in_interrupt()) ++ return; ++ ++ local_irq_save(flags); ++ ++ pending = local_softirq_pending(); ++ ++ if (pending) ++ execute_on_irq_stack(__do_softirq, 0); ++ ++ local_irq_restore(flags); + } + #endif /* CONFIG_IRQSTACKS */ + +--- a/arch/parisc/mm/init.c ++++ b/arch/parisc/mm/init.c +@@ -1077,7 +1077,7 @@ void flush_tlb_all(void) + { + int do_recycle; + +- inc_irq_stat(irq_tlb_count); ++ __inc_irq_stat(irq_tlb_count); + do_recycle = 0; + spin_lock(&sid_lock); + if (dirty_space_ids > RECYCLE_THRESHOLD) { +@@ -1098,7 +1098,7 @@ void flush_tlb_all(void) + #else + void flush_tlb_all(void) + { +- inc_irq_stat(irq_tlb_count); ++ __inc_irq_stat(irq_tlb_count); + spin_lock(&sid_lock); + flush_tlb_all_local(NULL); + recycle_sids(); diff --git a/queue-3.9/parisc-implement-irq-stacks.patch b/queue-3.9/parisc-implement-irq-stacks.patch new file mode 100644 index 00000000000..bf63137d187 --- /dev/null +++ b/queue-3.9/parisc-implement-irq-stacks.patch @@ -0,0 +1,178 @@ +From 200c880420a2c02a0899120ce52d801fad705b90 Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Tue, 7 May 2013 20:25:42 +0000 +Subject: parisc: implement irq stacks + +From: Helge Deller + +commit 200c880420a2c02a0899120ce52d801fad705b90 upstream. + +Default kernel stack size on parisc is 16k. During tests we found that the +kernel stack can easily grow beyond 13k, which leaves 3k left for irq +processing. + +This patch adds the possibility to activate an additional stack of 16k per CPU +which is being used during irq processing. This implementation does not yet +uses this irq stack for the irq bh handler. + +The assembler code for call_on_stack was heavily cleaned up by John +David Anglin. + +Signed-off-by: Helge Deller +CC: John David Anglin +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/Kconfig | 8 +++++++ + arch/parisc/include/asm/processor.h | 19 ++++++++++++++-- + arch/parisc/kernel/entry.S | 41 ++++++++++++++++++++++++++++++++++++ + arch/parisc/kernel/irq.c | 28 ++++++++++++++++++++++++ + 4 files changed, 94 insertions(+), 2 deletions(-) + +--- a/arch/parisc/Kconfig ++++ b/arch/parisc/Kconfig +@@ -241,6 +241,14 @@ config SMP + + If you don't know what to do here, say N. + ++config IRQSTACKS ++ bool "Use separate kernel stacks when processing interrupts" ++ default n ++ help ++ If you say Y here the kernel will use separate kernel stacks ++ for handling hard and soft interrupts. This can help avoid ++ overflowing the process kernel stacks. ++ + config HOTPLUG_CPU + bool + default y if SMP +--- a/arch/parisc/include/asm/processor.h ++++ b/arch/parisc/include/asm/processor.h +@@ -20,8 +20,6 @@ + + #endif /* __ASSEMBLY__ */ + +-#define KERNEL_STACK_SIZE (4*PAGE_SIZE) +- + /* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). +@@ -61,6 +59,23 @@ + #ifndef __ASSEMBLY__ + + /* ++ * IRQ STACK - used for irq handler ++ */ ++#ifdef __KERNEL__ ++ ++#define IRQ_STACK_SIZE (4096 << 2) /* 16k irq stack size */ ++ ++union irq_stack_union { ++ unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)]; ++}; ++ ++DECLARE_PER_CPU(union irq_stack_union, irq_stack_union); ++ ++void call_on_stack(unsigned long p1, void *func, unsigned long new_stack); ++ ++#endif /* __KERNEL__ */ ++ ++/* + * Data detected about CPUs at boot time which is the same for all CPU's. + * HP boxes are SMP - ie identical processors. + * +--- a/arch/parisc/kernel/entry.S ++++ b/arch/parisc/kernel/entry.S +@@ -2013,6 +2013,47 @@ ftrace_stub: + ENDPROC(return_to_handler) + #endif /* CONFIG_FUNCTION_TRACER */ + ++#ifdef CONFIG_IRQSTACKS ++/* void call_on_stack(unsigned long param1, void *func, ++ unsigned long new_stack) */ ++ENTRY(call_on_stack) ++ copy %sp, %r1 ++ ++ /* Regarding the HPPA calling conventions for function pointers, ++ we assume the PIC register is not changed across call. For ++ CONFIG_64BIT, the argument pointer is left to point at the ++ argument region allocated for the call to call_on_stack. */ ++# ifdef CONFIG_64BIT ++ /* Switch to new stack. We allocate two 128 byte frames. */ ++ ldo 256(%arg2), %sp ++ /* Save previous stack pointer and return pointer in frame marker */ ++ STREG %rp, -144(%sp) ++ /* Calls always use function descriptor */ ++ LDREG 16(%arg1), %arg1 ++ bve,l (%arg1), %rp ++ STREG %r1, -136(%sp) ++ LDREG -144(%sp), %rp ++ bve (%rp) ++ LDREG -136(%sp), %sp ++# else ++ /* Switch to new stack. We allocate two 64 byte frames. */ ++ ldo 128(%arg2), %sp ++ /* Save previous stack pointer and return pointer in frame marker */ ++ STREG %r1, -68(%sp) ++ STREG %rp, -84(%sp) ++ /* Calls use function descriptor if PLABEL bit is set */ ++ bb,>=,n %arg1, 30, 1f ++ depwi 0,31,2, %arg1 ++ LDREG 0(%arg1), %arg1 ++1: ++ be,l 0(%sr4,%arg1), %sr0, %r31 ++ copy %r31, %rp ++ LDREG -84(%sp), %rp ++ bv (%rp) ++ LDREG -68(%sp), %sp ++# endif /* CONFIG_64BIT */ ++ENDPROC(call_on_stack) ++#endif /* CONFIG_IRQSTACKS */ + + get_register: + /* +--- a/arch/parisc/kernel/irq.c ++++ b/arch/parisc/kernel/irq.c +@@ -358,6 +358,29 @@ static inline void stack_overflow_check( + #endif + } + ++#ifdef CONFIG_IRQSTACKS ++DEFINE_PER_CPU(union irq_stack_union, irq_stack_union); ++ ++static void execute_on_irq_stack(void *func, unsigned long param1) ++{ ++ unsigned long *irq_stack_start; ++ unsigned long irq_stack; ++ int cpu = smp_processor_id(); ++ ++ irq_stack_start = &per_cpu(irq_stack_union, cpu).stack[0]; ++ irq_stack = (unsigned long) irq_stack_start; ++ irq_stack = ALIGN(irq_stack, 16); /* align for stack frame usage */ ++ ++ BUG_ON(*irq_stack_start); /* report bug if we were called recursive. */ ++ *irq_stack_start = 1; ++ ++ /* This is where we switch to the IRQ stack. */ ++ call_on_stack(param1, func, irq_stack); ++ ++ *irq_stack_start = 0; ++} ++#endif /* CONFIG_IRQSTACKS */ ++ + /* ONLY called from entry.S:intr_extint() */ + void do_cpu_irq_mask(struct pt_regs *regs) + { +@@ -393,7 +416,12 @@ void do_cpu_irq_mask(struct pt_regs *reg + } + #endif + stack_overflow_check(regs); ++ ++#ifdef CONFIG_IRQSTACKS ++ execute_on_irq_stack(&generic_handle_irq, irq); ++#else + generic_handle_irq(irq); ++#endif /* CONFIG_IRQSTACKS */ + + out: + irq_exit(); diff --git a/queue-3.9/parisc-kernel-using-strlcpy-instead-of-strcpy.patch b/queue-3.9/parisc-kernel-using-strlcpy-instead-of-strcpy.patch new file mode 100644 index 00000000000..085aa5241c7 --- /dev/null +++ b/queue-3.9/parisc-kernel-using-strlcpy-instead-of-strcpy.patch @@ -0,0 +1,33 @@ +From ea99b1adf22abd62bdcf14b1c9a0a4d3664eefd8 Mon Sep 17 00:00:00 2001 +From: Chen Gang +Date: Thu, 30 May 2013 01:18:43 +0000 +Subject: parisc: kernel: using strlcpy() instead of strcpy() + +From: Chen Gang + +commit ea99b1adf22abd62bdcf14b1c9a0a4d3664eefd8 upstream. + +'boot_args' is an input args, and 'boot_command_line' has a fix length. +So use strlcpy() instead of strcpy() to avoid memory overflow. + +Signed-off-by: Chen Gang +Acked-by: Kyle McMartin +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/kernel/setup.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/parisc/kernel/setup.c ++++ b/arch/parisc/kernel/setup.c +@@ -69,7 +69,8 @@ void __init setup_cmdline(char **cmdline + /* called from hpux boot loader */ + boot_command_line[0] = '\0'; + } else { +- strcpy(boot_command_line, (char *)__va(boot_args[1])); ++ strlcpy(boot_command_line, (char *)__va(boot_args[1]), ++ COMMAND_LINE_SIZE); + + #ifdef CONFIG_BLK_DEV_INITRD + if (boot_args[2] != 0) /* did palo pass us a ramdisk? */ diff --git a/queue-3.9/parisc-make-interrupt-and-interruption-stack-allocation-reentrant.patch b/queue-3.9/parisc-make-interrupt-and-interruption-stack-allocation-reentrant.patch new file mode 100644 index 00000000000..12ff3d35a97 --- /dev/null +++ b/queue-3.9/parisc-make-interrupt-and-interruption-stack-allocation-reentrant.patch @@ -0,0 +1,105 @@ +From b63a2bbc0b9b106a93e11952ab057e2408f2eb02 Mon Sep 17 00:00:00 2001 +From: John David Anglin +Date: Mon, 20 May 2013 16:42:53 +0000 +Subject: parisc: make interrupt and interruption stack allocation reentrant + +From: John David Anglin + +commit b63a2bbc0b9b106a93e11952ab057e2408f2eb02 upstream. + +The get_stack_use_cr30 and get_stack_use_r30 macros allocate a stack +frame for external interrupts and interruptions requiring a stack frame. +They are currently not reentrant in that they save register context +before the stack is set or adjusted. + +I have observed a number of system crashes where there was clear +evidence of stack corruption during interrupt processing, and as a +result register corruption. Some interruptions can still occur during +interruption processing, however external interrupts are disabled and +data TLB misses don't occur for absolute accesses. So, it's not entirely +clear what triggers this issue. Also, if an interruption occurs when +Q=0, it is generally not possible to recover as the shadowed registers +are not copied. + +The attached patch reworks the get_stack_use_cr30 and get_stack_use_r30 +macros to allocate stack before doing register saves. The new code is a +couple of instructions shorter than the old implementation. Thus, it's +an improvement even if it doesn't fully resolve the stack corruption +issue. Based on limited testing, it improves SMP system stability. + +Signed-off-by: John David Anglin +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/include/asm/assembly.h | 1 - + arch/parisc/kernel/entry.S | 19 ++++++++++--------- + 2 files changed, 10 insertions(+), 10 deletions(-) + +--- a/arch/parisc/include/asm/assembly.h ++++ b/arch/parisc/include/asm/assembly.h +@@ -438,7 +438,6 @@ + SAVE_SP (%sr4, PT_SR4 (\regs)) + SAVE_SP (%sr5, PT_SR5 (\regs)) + SAVE_SP (%sr6, PT_SR6 (\regs)) +- SAVE_SP (%sr7, PT_SR7 (\regs)) + + SAVE_CR (%cr17, PT_IASQ0(\regs)) + mtctl %r0, %cr17 +--- a/arch/parisc/kernel/entry.S ++++ b/arch/parisc/kernel/entry.S +@@ -65,15 +65,11 @@ + rsm PSW_SM_I, %r0 /* barrier for "Relied upon Translation */ + mtsp %r0, %sr4 + mtsp %r0, %sr5 +- mfsp %sr7, %r1 +- or,= %r0,%r1,%r0 /* Only save sr7 in sr3 if sr7 != 0 */ +- mtsp %r1, %sr3 ++ mtsp %r0, %sr6 + tovirt_r1 %r29 + load32 KERNEL_PSW, %r1 + + rsm PSW_SM_QUIET,%r0 /* second "heavy weight" ctl op */ +- mtsp %r0, %sr6 +- mtsp %r0, %sr7 + mtctl %r0, %cr17 /* Clear IIASQ tail */ + mtctl %r0, %cr17 /* Clear IIASQ head */ + mtctl %r1, %ipsw +@@ -119,17 +115,20 @@ + + /* we save the registers in the task struct */ + ++ copy %r30, %r17 + mfctl %cr30, %r1 ++ ldo THREAD_SZ_ALGN(%r1), %r30 ++ mtsp %r0,%sr7 ++ mtsp %r16,%sr3 + tophys %r1,%r9 + LDREG TI_TASK(%r9), %r1 /* thread_info -> task_struct */ + tophys %r1,%r9 + ldo TASK_REGS(%r9),%r9 +- STREG %r30, PT_GR30(%r9) ++ STREG %r17,PT_GR30(%r9) + STREG %r29,PT_GR29(%r9) + STREG %r26,PT_GR26(%r9) ++ STREG %r16,PT_SR7(%r9) + copy %r9,%r29 +- mfctl %cr30, %r1 +- ldo THREAD_SZ_ALGN(%r1), %r30 + .endm + + .macro get_stack_use_r30 +@@ -137,10 +136,12 @@ + /* we put a struct pt_regs on the stack and save the registers there */ + + tophys %r30,%r9 +- STREG %r30,PT_GR30(%r9) ++ copy %r30,%r1 + ldo PT_SZ_ALGN(%r30),%r30 ++ STREG %r1,PT_GR30(%r9) + STREG %r29,PT_GR29(%r9) + STREG %r26,PT_GR26(%r9) ++ STREG %r16,PT_SR7(%r9) + copy %r9,%r29 + .endm + diff --git a/queue-3.9/parisc-memory-overflow-name-length-is-too-short-for-using.patch b/queue-3.9/parisc-memory-overflow-name-length-is-too-short-for-using.patch new file mode 100644 index 00000000000..f7d06b81126 --- /dev/null +++ b/queue-3.9/parisc-memory-overflow-name-length-is-too-short-for-using.patch @@ -0,0 +1,39 @@ +From 3f108de96ba449a8df3d7e3c053bf890fee2cb95 Mon Sep 17 00:00:00 2001 +From: Chen Gang +Date: Mon, 27 May 2013 04:57:09 +0000 +Subject: parisc: memory overflow, 'name' length is too short for using + +From: Chen Gang + +commit 3f108de96ba449a8df3d7e3c053bf890fee2cb95 upstream. + +'path.bc[i]' can be asigned by PCI_SLOT() which can '> 10', so sizeof(6 +* "%u:" + "%u" + '\0') may be 21. + +Since 'name' length is 20, it may be memory overflow. + +And 'path.bc[i]' is 'unsigned char' for printing, we can be sure the +max length of 'name' must be less than 28. + +So simplify thinking, we can use 28 instead of 20 directly, and do not +think of whether 'patchc.bc[i]' can '> 100'. + +Signed-off-by: Chen Gang +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/kernel/drivers.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/parisc/kernel/drivers.c ++++ b/arch/parisc/kernel/drivers.c +@@ -394,7 +394,7 @@ EXPORT_SYMBOL(print_pci_hwpath); + static void setup_bus_id(struct parisc_device *padev) + { + struct hardware_path path; +- char name[20]; ++ char name[28]; + char *output = name; + int i; + diff --git a/queue-3.9/parisc-more-irq-statistics-in-proc-interrupts.patch b/queue-3.9/parisc-more-irq-statistics-in-proc-interrupts.patch new file mode 100644 index 00000000000..4fec5fda3bf --- /dev/null +++ b/queue-3.9/parisc-more-irq-statistics-in-proc-interrupts.patch @@ -0,0 +1,196 @@ +From cd85d5514d5c4d7e78abac923fc032457d0c5091 Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Mon, 6 May 2013 19:20:26 +0000 +Subject: parisc: more irq statistics in /proc/interrupts + +From: Helge Deller + +commit cd85d5514d5c4d7e78abac923fc032457d0c5091 upstream. + +Add framework and initial values for more fine grained statistics in +/proc/interrupts. + +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/include/asm/hardirq.h | 36 ++++++++++++++++++++++++++- + arch/parisc/include/asm/processor.h | 1 + arch/parisc/kernel/irq.c | 48 +++++++++++++++++++++++++++++++++++- + arch/parisc/kernel/smp.c | 3 +- + arch/parisc/mm/init.c | 2 + + 5 files changed, 86 insertions(+), 4 deletions(-) + +--- a/arch/parisc/include/asm/hardirq.h ++++ b/arch/parisc/include/asm/hardirq.h +@@ -1,11 +1,45 @@ + /* hardirq.h: PA-RISC hard IRQ support. + * + * Copyright (C) 2001 Matthew Wilcox ++ * Copyright (C) 2013 Helge Deller + */ + + #ifndef _PARISC_HARDIRQ_H + #define _PARISC_HARDIRQ_H + +-#include ++#include ++#include ++#include ++ ++typedef struct { ++ unsigned int __softirq_pending; ++#ifdef CONFIG_DEBUG_STACKOVERFLOW ++ unsigned int kernel_stack_usage; ++#endif ++#ifdef CONFIG_SMP ++ unsigned int irq_resched_count; ++ unsigned int irq_call_count; ++ /* ++ * irq_tlb_count is double-counted in irq_call_count, so it must be ++ * subtracted from irq_call_count when displaying irq_call_count ++ */ ++ unsigned int irq_tlb_count; ++#endif ++} ____cacheline_aligned irq_cpustat_t; ++ ++DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); ++ ++#define __ARCH_IRQ_STAT ++#define __IRQ_STAT(cpu, member) (irq_stat[cpu].member) ++#define inc_irq_stat(member) this_cpu_inc(irq_stat.member) ++#define local_softirq_pending() this_cpu_read(irq_stat.__softirq_pending) ++ ++#define __ARCH_SET_SOFTIRQ_PENDING ++ ++#define set_softirq_pending(x) \ ++ this_cpu_write(irq_stat.__softirq_pending, (x)) ++#define or_softirq_pending(x) this_cpu_or(irq_stat.__softirq_pending, (x)) ++ ++#define ack_bad_irq(irq) WARN(1, "unexpected IRQ trap at vector %02x\n", irq) + + #endif /* _PARISC_HARDIRQ_H */ +--- a/arch/parisc/include/asm/processor.h ++++ b/arch/parisc/include/asm/processor.h +@@ -112,7 +112,6 @@ struct cpuinfo_parisc { + unsigned long txn_addr; /* MMIO addr of EIR or id_eid */ + #ifdef CONFIG_SMP + unsigned long pending_ipi; /* bitmap of type ipi_message_type */ +- unsigned long ipi_count; /* number ipi Interrupts */ + #endif + unsigned long bh_count; /* number of times bh was invoked */ + unsigned long prof_counter; /* per CPU profiling support */ +--- a/arch/parisc/kernel/irq.c ++++ b/arch/parisc/kernel/irq.c +@@ -152,6 +152,40 @@ static struct irq_chip cpu_interrupt_typ + .irq_retrigger = NULL, + }; + ++DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); ++#define irq_stats(x) (&per_cpu(irq_stat, x)) ++ ++/* ++ * /proc/interrupts printing for arch specific interrupts ++ */ ++int arch_show_interrupts(struct seq_file *p, int prec) ++{ ++ int j; ++ ++#ifdef CONFIG_DEBUG_STACKOVERFLOW ++ seq_printf(p, "%*s: ", prec, "STK"); ++ for_each_online_cpu(j) ++ seq_printf(p, "%10u ", irq_stats(j)->kernel_stack_usage); ++ seq_printf(p, " Kernel stack usage\n"); ++#endif ++#ifdef CONFIG_SMP ++ seq_printf(p, "%*s: ", prec, "RES"); ++ for_each_online_cpu(j) ++ seq_printf(p, "%10u ", irq_stats(j)->irq_resched_count); ++ seq_printf(p, " Rescheduling interrupts\n"); ++ seq_printf(p, "%*s: ", prec, "CAL"); ++ for_each_online_cpu(j) ++ seq_printf(p, "%10u ", irq_stats(j)->irq_call_count - ++ irq_stats(j)->irq_tlb_count); ++ seq_printf(p, " Function call interrupts\n"); ++ seq_printf(p, "%*s: ", prec, "TLB"); ++ for_each_online_cpu(j) ++ seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count); ++ seq_printf(p, " TLB shootdowns\n"); ++#endif ++ return 0; ++} ++ + int show_interrupts(struct seq_file *p, void *v) + { + int i = *(loff_t *) v, j; +@@ -219,6 +253,9 @@ int show_interrupts(struct seq_file *p, + raw_spin_unlock_irqrestore(&desc->lock, flags); + } + ++ if (i == NR_IRQS) ++ arch_show_interrupts(p, 3); ++ + return 0; + } + +@@ -340,13 +377,22 @@ static inline void stack_overflow_check( + /* Our stack starts directly behind the thread_info struct. */ + unsigned long stack_start = (unsigned long) current_thread_info(); + unsigned long sp = regs->gr[30]; ++ unsigned long stack_usage; ++ unsigned int *last_usage; + + /* if sr7 != 0, we interrupted a userspace process which we do not want + * to check for stack overflow. We will only check the kernel stack. */ + if (regs->sr[7]) + return; + +- if (likely((sp - stack_start) < (THREAD_SIZE - STACK_MARGIN))) ++ /* calculate kernel stack usage */ ++ stack_usage = sp - stack_start; ++ last_usage = &per_cpu(irq_stat.kernel_stack_usage, smp_processor_id()); ++ ++ if (unlikely(stack_usage > *last_usage)) ++ *last_usage = stack_usage; ++ ++ if (likely(stack_usage < (THREAD_SIZE - STACK_MARGIN))) + return; + + pr_emerg("stackcheck: %s will most likely overflow kernel stack " +--- a/arch/parisc/kernel/smp.c ++++ b/arch/parisc/kernel/smp.c +@@ -127,7 +127,7 @@ ipi_interrupt(int irq, void *dev_id) + unsigned long flags; + + /* Count this now; we may make a call that never returns. */ +- p->ipi_count++; ++ inc_irq_stat(irq_call_count); + + mb(); /* Order interrupt and bit testing. */ + +@@ -155,6 +155,7 @@ ipi_interrupt(int irq, void *dev_id) + + case IPI_RESCHEDULE: + smp_debug(100, KERN_DEBUG "CPU%d IPI_RESCHEDULE\n", this_cpu); ++ inc_irq_stat(irq_resched_count); + scheduler_ipi(); + break; + +--- a/arch/parisc/mm/init.c ++++ b/arch/parisc/mm/init.c +@@ -1077,6 +1077,7 @@ void flush_tlb_all(void) + { + int do_recycle; + ++ inc_irq_stat(irq_tlb_count); + do_recycle = 0; + spin_lock(&sid_lock); + if (dirty_space_ids > RECYCLE_THRESHOLD) { +@@ -1097,6 +1098,7 @@ void flush_tlb_all(void) + #else + void flush_tlb_all(void) + { ++ inc_irq_stat(irq_tlb_count); + spin_lock(&sid_lock); + flush_tlb_all_local(NULL); + recycle_sids(); diff --git a/queue-3.9/parisc-parport0-fix-this-legacy-no-device-port-driver.patch b/queue-3.9/parisc-parport0-fix-this-legacy-no-device-port-driver.patch new file mode 100644 index 00000000000..952b7ee45ce --- /dev/null +++ b/queue-3.9/parisc-parport0-fix-this-legacy-no-device-port-driver.patch @@ -0,0 +1,67 @@ +From 4edb38695d9a3cd62739f8595e21f36f0aabf4c2 Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Thu, 30 May 2013 21:06:39 +0000 +Subject: parisc: parport0: fix this legacy no-device port driver! + +From: Helge Deller + +commit 4edb38695d9a3cd62739f8595e21f36f0aabf4c2 upstream. + +Fix the above kernel error from parport_announce_port() on 32bit GSC +machines (e.g. B160L). The parport driver requires now a pointer to the +device struct. + +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/parport/parport_gsc.c | 6 +++--- + drivers/parport/parport_gsc.h | 2 +- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/parport/parport_gsc.c ++++ b/drivers/parport/parport_gsc.c +@@ -234,7 +234,7 @@ static int parport_PS2_supported(struct + + struct parport *parport_gsc_probe_port(unsigned long base, + unsigned long base_hi, int irq, +- int dma, struct pci_dev *dev) ++ int dma, struct parisc_device *padev) + { + struct parport_gsc_private *priv; + struct parport_operations *ops; +@@ -258,7 +258,6 @@ struct parport *parport_gsc_probe_port(u + priv->ctr_writable = 0xff; + priv->dma_buf = 0; + priv->dma_handle = 0; +- priv->dev = dev; + p->base = base; + p->base_hi = base_hi; + p->irq = irq; +@@ -282,6 +281,7 @@ struct parport *parport_gsc_probe_port(u + return NULL; + } + ++ p->dev = &padev->dev; + p->base_hi = base_hi; + p->modes = tmp.modes; + p->size = (p->modes & PARPORT_MODE_EPP)?8:3; +@@ -373,7 +373,7 @@ static int parport_init_chip(struct pari + } + + p = parport_gsc_probe_port(port, 0, dev->irq, +- /* PARPORT_IRQ_NONE */ PARPORT_DMA_NONE, NULL); ++ /* PARPORT_IRQ_NONE */ PARPORT_DMA_NONE, dev); + if (p) + parport_count++; + dev_set_drvdata(&dev->dev, p); +--- a/drivers/parport/parport_gsc.h ++++ b/drivers/parport/parport_gsc.h +@@ -217,6 +217,6 @@ extern void parport_gsc_dec_use_count(vo + extern struct parport *parport_gsc_probe_port(unsigned long base, + unsigned long base_hi, + int irq, int dma, +- struct pci_dev *dev); ++ struct parisc_device *padev); + + #endif /* __DRIVERS_PARPORT_PARPORT_GSC_H */ diff --git a/queue-3.9/parisc-provide-pci_mmap_page_range-for-parisc.patch b/queue-3.9/parisc-provide-pci_mmap_page_range-for-parisc.patch new file mode 100644 index 00000000000..12f678b765b --- /dev/null +++ b/queue-3.9/parisc-provide-pci_mmap_page_range-for-parisc.patch @@ -0,0 +1,69 @@ +From 2cc7138f4347df939ce03f313e3d87794bab36f8 Mon Sep 17 00:00:00 2001 +From: Thomas Bogendoerfer +Date: Fri, 14 Jun 2013 09:05:41 +0200 +Subject: parisc: provide pci_mmap_page_range() for parisc + +From: Thomas Bogendoerfer + +commit 2cc7138f4347df939ce03f313e3d87794bab36f8 upstream. + +pci_mmap_page_range() is needed for X11-server support on C8000 with ATI +FireGL card. + +Signed-off-by Thomas Bogendoerfer +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/include/asm/pci.h | 5 +++++ + arch/parisc/kernel/pci.c | 27 +++++++++++++++++++++++++++ + 2 files changed, 32 insertions(+) + +--- a/arch/parisc/include/asm/pci.h ++++ b/arch/parisc/include/asm/pci.h +@@ -225,4 +225,9 @@ static inline int pci_get_legacy_ide_irq + return channel ? 15 : 14; + } + ++#define HAVE_PCI_MMAP ++ ++extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, ++ enum pci_mmap_state mmap_state, int write_combine); ++ + #endif /* __ASM_PARISC_PCI_H */ +--- a/arch/parisc/kernel/pci.c ++++ b/arch/parisc/kernel/pci.c +@@ -220,6 +220,33 @@ resource_size_t pcibios_align_resource(v + } + + ++int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, ++ enum pci_mmap_state mmap_state, int write_combine) ++{ ++ unsigned long prot; ++ ++ /* ++ * I/O space can be accessed via normal processor loads and stores on ++ * this platform but for now we elect not to do this and portable ++ * drivers should not do this anyway. ++ */ ++ if (mmap_state == pci_mmap_io) ++ return -EINVAL; ++ ++ if (write_combine) ++ return -EINVAL; ++ ++ /* ++ * Ignore write-combine; for now only return uncached mappings. ++ */ ++ prot = pgprot_val(vma->vm_page_prot); ++ prot |= _PAGE_NO_CACHE; ++ vma->vm_page_prot = __pgprot(prot); ++ ++ return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, ++ vma->vm_end - vma->vm_start, vma->vm_page_prot); ++} ++ + /* + * A driver is enabling the device. We make sure that all the appropriate + * bits are set to allow the device to operate as the driver is expecting. diff --git a/queue-3.9/parisc-remove-the-second-argument-of-kmap_atomic.patch b/queue-3.9/parisc-remove-the-second-argument-of-kmap_atomic.patch new file mode 100644 index 00000000000..cb3a808996e --- /dev/null +++ b/queue-3.9/parisc-remove-the-second-argument-of-kmap_atomic.patch @@ -0,0 +1,45 @@ +From 1ab4ce762370b82870834899e49c08129d7ae271 Mon Sep 17 00:00:00 2001 +From: Zhao Hongjiang +Date: Tue, 7 May 2013 16:18:12 -0700 +Subject: parisc: remove the second argument of kmap_atomic() + +From: Zhao Hongjiang + +commit 1ab4ce762370b82870834899e49c08129d7ae271 upstream. + +kmap_atomic() requires only one argument now. + +Signed-off-by: Zhao Hongjiang +Cc: "James E.J. Bottomley" +Cc: Helge Deller +Cc: Rolf Eike Beer +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/kernel/cache.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/parisc/kernel/cache.c ++++ b/arch/parisc/kernel/cache.c +@@ -606,7 +606,7 @@ void clear_user_highpage(struct page *pa + /* Clear using TMPALIAS region. The page doesn't need to + be flushed but the kernel mapping needs to be purged. */ + +- vto = kmap_atomic(page, KM_USER0); ++ vto = kmap_atomic(page); + + /* The PA-RISC 2.0 Architecture book states on page F-6: + "Before a write-capable translation is enabled, *all* +@@ -641,8 +641,8 @@ void copy_user_highpage(struct page *to, + the `to' page must be flushed in copy_user_page_asm since + it can be used to bring in executable code. */ + +- vfrom = kmap_atomic(from, KM_USER0); +- vto = kmap_atomic(to, KM_USER1); ++ vfrom = kmap_atomic(from); ++ vto = kmap_atomic(to); + + purge_kernel_dcache_page_asm((unsigned long)vto); + purge_tlb_start(flags); diff --git a/queue-3.9/parisc-rename-config_pa7100-to-config_pa7000.patch b/queue-3.9/parisc-rename-config_pa7100-to-config_pa7000.patch new file mode 100644 index 00000000000..e1b772c10ab --- /dev/null +++ b/queue-3.9/parisc-rename-config_pa7100-to-config_pa7000.patch @@ -0,0 +1,33 @@ +From 766039022a480ede847659daaa78772bdcc598ae Mon Sep 17 00:00:00 2001 +From: Paul Bolle +Date: Wed, 29 May 2013 09:56:58 +0000 +Subject: parisc: rename "CONFIG_PA7100" to "CONFIG_PA7000" + +From: Paul Bolle + +commit 766039022a480ede847659daaa78772bdcc598ae upstream. + +There's a Makefile line setting cflags for CONFIG_PA7100. But that +Kconfig macro doesn't exist. There is a Kconfig symbol PA7000, which +covers both PA7000 and PA7100 processors. So let's use the corresponding +Kconfig macro. + +Signed-off-by: Paul Bolle +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/parisc/Makefile ++++ b/arch/parisc/Makefile +@@ -66,7 +66,7 @@ KBUILD_CFLAGS_KERNEL += -mlong-calls + endif + + # select which processor to optimise for +-cflags-$(CONFIG_PA7100) += -march=1.1 -mschedule=7100 ++cflags-$(CONFIG_PA7000) += -march=1.1 -mschedule=7100 + cflags-$(CONFIG_PA7200) += -march=1.1 -mschedule=7200 + cflags-$(CONFIG_PA7100LC) += -march=1.1 -mschedule=7100LC + cflags-$(CONFIG_PA7300LC) += -march=1.1 -mschedule=7300 diff --git a/queue-3.9/parisc-show-number-of-fpe-and-unaligned-access-handler-calls-in-proc-interrupts.patch b/queue-3.9/parisc-show-number-of-fpe-and-unaligned-access-handler-calls-in-proc-interrupts.patch new file mode 100644 index 00000000000..0469e3bc2ff --- /dev/null +++ b/queue-3.9/parisc-show-number-of-fpe-and-unaligned-access-handler-calls-in-proc-interrupts.patch @@ -0,0 +1,79 @@ +From d0c3be806a3fe7f4abdb0f7e7287addb55e73f35 Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Sat, 18 May 2013 19:35:44 +0000 +Subject: parisc: show number of FPE and unaligned access handler calls in /proc/interrupts + +From: Helge Deller + +commit d0c3be806a3fe7f4abdb0f7e7287addb55e73f35 upstream. + +Show number of floating point assistant and unaligned access fixup +handler in /proc/interrupts file. + +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/include/asm/hardirq.h | 2 ++ + arch/parisc/kernel/irq.c | 8 ++++++++ + arch/parisc/kernel/traps.c | 1 + + arch/parisc/kernel/unaligned.c | 3 +++ + 4 files changed, 14 insertions(+) + +--- a/arch/parisc/include/asm/hardirq.h ++++ b/arch/parisc/include/asm/hardirq.h +@@ -28,6 +28,8 @@ typedef struct { + unsigned int irq_resched_count; + unsigned int irq_call_count; + #endif ++ unsigned int irq_unaligned_count; ++ unsigned int irq_fpassist_count; + unsigned int irq_tlb_count; + } ____cacheline_aligned irq_cpustat_t; + +--- a/arch/parisc/kernel/irq.c ++++ b/arch/parisc/kernel/irq.c +@@ -188,6 +188,14 @@ int arch_show_interrupts(struct seq_file + seq_printf(p, "%10u ", irq_stats(j)->irq_call_count); + seq_puts(p, " Function call interrupts\n"); + #endif ++ seq_printf(p, "%*s: ", prec, "UAH"); ++ for_each_online_cpu(j) ++ seq_printf(p, "%10u ", irq_stats(j)->irq_unaligned_count); ++ seq_puts(p, " Unaligned access handler traps\n"); ++ seq_printf(p, "%*s: ", prec, "FPA"); ++ for_each_online_cpu(j) ++ seq_printf(p, "%10u ", irq_stats(j)->irq_fpassist_count); ++ seq_puts(p, " Floating point assist traps\n"); + seq_printf(p, "%*s: ", prec, "TLB"); + for_each_online_cpu(j) + seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count); +--- a/arch/parisc/kernel/traps.c ++++ b/arch/parisc/kernel/traps.c +@@ -652,6 +652,7 @@ void notrace handle_interruption(int cod + case 14: + /* Assist Exception Trap, i.e. floating point exception. */ + die_if_kernel("Floating point exception", regs, 0); /* quiet */ ++ __inc_irq_stat(irq_fpassist_count); + handle_fpe(regs); + return; + +--- a/arch/parisc/kernel/unaligned.c ++++ b/arch/parisc/kernel/unaligned.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + + /* #define DEBUG_UNALIGNED 1 */ + +@@ -454,6 +455,8 @@ void handle_unaligned(struct pt_regs *re + struct siginfo si; + register int flop=0; /* true if this is a flop */ + ++ __inc_irq_stat(irq_unaligned_count); ++ + /* log a message with pacing */ + if (user_mode(regs)) { + if (current->thread.flags & PARISC_UAC_SIGBUS) { diff --git a/queue-3.9/parisc-tlb-flush-counting-fix-for-smp-and-up.patch b/queue-3.9/parisc-tlb-flush-counting-fix-for-smp-and-up.patch new file mode 100644 index 00000000000..de622e08621 --- /dev/null +++ b/queue-3.9/parisc-tlb-flush-counting-fix-for-smp-and-up.patch @@ -0,0 +1,88 @@ +From 0fc537d1d655cdae69b489dbba46ad617cfc1373 Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Tue, 7 May 2013 21:42:47 +0000 +Subject: parisc: tlb flush counting fix for SMP and UP + +From: Helge Deller + +commit 0fc537d1d655cdae69b489dbba46ad617cfc1373 upstream. + +Fix up build error on UP and show correctly number of function call +(ipi) irqs. + +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/include/asm/hardirq.h | 6 +----- + arch/parisc/include/asm/tlbflush.h | 2 ++ + arch/parisc/kernel/irq.c | 5 ++--- + arch/parisc/kernel/smp.c | 11 ----------- + 4 files changed, 5 insertions(+), 19 deletions(-) + +--- a/arch/parisc/include/asm/hardirq.h ++++ b/arch/parisc/include/asm/hardirq.h +@@ -19,12 +19,8 @@ typedef struct { + #ifdef CONFIG_SMP + unsigned int irq_resched_count; + unsigned int irq_call_count; +- /* +- * irq_tlb_count is double-counted in irq_call_count, so it must be +- * subtracted from irq_call_count when displaying irq_call_count +- */ +- unsigned int irq_tlb_count; + #endif ++ unsigned int irq_tlb_count; + } ____cacheline_aligned irq_cpustat_t; + + DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); +--- a/arch/parisc/include/asm/tlbflush.h ++++ b/arch/parisc/include/asm/tlbflush.h +@@ -22,6 +22,8 @@ extern spinlock_t pa_tlb_lock; + extern void flush_tlb_all(void); + extern void flush_tlb_all_local(void *); + ++#define smp_flush_tlb_all() flush_tlb_all() ++ + /* + * flush_tlb_mm() + * +--- a/arch/parisc/kernel/irq.c ++++ b/arch/parisc/kernel/irq.c +@@ -175,14 +175,13 @@ int arch_show_interrupts(struct seq_file + seq_printf(p, " Rescheduling interrupts\n"); + seq_printf(p, "%*s: ", prec, "CAL"); + for_each_online_cpu(j) +- seq_printf(p, "%10u ", irq_stats(j)->irq_call_count - +- irq_stats(j)->irq_tlb_count); ++ seq_printf(p, "%10u ", irq_stats(j)->irq_call_count); + seq_printf(p, " Function call interrupts\n"); ++#endif + seq_printf(p, "%*s: ", prec, "TLB"); + for_each_online_cpu(j) + seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count); + seq_printf(p, " TLB shootdowns\n"); +-#endif + return 0; + } + +--- a/arch/parisc/kernel/smp.c ++++ b/arch/parisc/kernel/smp.c +@@ -264,17 +264,6 @@ void arch_send_call_function_single_ipi( + } + + /* +- * Flush all other CPU's tlb and then mine. Do this with on_each_cpu() +- * as we want to ensure all TLB's flushed before proceeding. +- */ +- +-void +-smp_flush_tlb_all(void) +-{ +- on_each_cpu(flush_tlb_all_local, NULL, 1); +-} +- +-/* + * Called by secondaries to update state and initialize CPU registers. + */ + static void __init diff --git a/queue-3.9/series b/queue-3.9/series index 4aa326c07f4..86c8aeb4061 100644 --- a/queue-3.9/series +++ b/queue-3.9/series @@ -9,3 +9,21 @@ clk-remove-notifier-from-list-before-freeing-it.patch tilepro-work-around-module-link-error-with-gcc-4.7.patch rtlwifi-rtl8192cu-fix-problem-in-connecting-to-wep-or-wpa-1-networks.patch brcmfmac-turn-off-arp-offloading-when-configured-for-ap.patch +parisc-add-kernel-stack-overflow-check.patch +parisc-implement-irq-stacks.patch +parisc-more-irq-statistics-in-proc-interrupts.patch +parisc-tlb-flush-counting-fix-for-smp-and-up.patch +parisc-remove-the-second-argument-of-kmap_atomic.patch +parisc-implement-irq-stacks-part-2-v2.patch +parisc-add-rp5470-entry-to-machine-database.patch +parisc-show-number-of-fpe-and-unaligned-access-handler-calls-in-proc-interrupts.patch +parisc-make-interrupt-and-interruption-stack-allocation-reentrant.patch +parisc-fix-irq-stack-on-up-and-smp.patch +parisc-memory-overflow-name-length-is-too-short-for-using.patch +parisc-fix-kernel-bug-at-arch-parisc-include-asm-mmzone.h-50.patch +parisc-rename-config_pa7100-to-config_pa7000.patch +parisc-kernel-using-strlcpy-instead-of-strcpy.patch +parisc-parport0-fix-this-legacy-no-device-port-driver.patch +parisc-fix-kernel-bug-at-arch-parisc-include-asm-mmzone.h-50-part-2.patch +parisc-fix-serial-ports-on-c8000-workstation.patch +parisc-provide-pci_mmap_page_range-for-parisc.patch