From 91887a362984324e254473e92820758c8e658f78 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 16 Mar 2009 14:19:37 +1030 Subject: cpumask: arch_send_call_function_ipi_mask: parisc We're weaning the core code off handing cpumask's around on-stack. This introduces arch_send_call_function_ipi_mask(), and by defining it, the old arch_send_call_function_ipi is defined by the core code. We also take the chance to change send_IPI_mask() and use the new for_each_cpu() iterator. Signed-off-by: Rusty Russell diff --git a/arch/parisc/include/asm/smp.h b/arch/parisc/include/asm/smp.h index 6ef4b78..21eb45a 100644 --- a/arch/parisc/include/asm/smp.h +++ b/arch/parisc/include/asm/smp.h @@ -29,7 +29,8 @@ extern void smp_send_reschedule(int cpu); extern void smp_send_all_nop(void); extern void arch_send_call_function_single_ipi(int cpu); -extern void arch_send_call_function_ipi(cpumask_t mask); +extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); +#define arch_send_call_function_ipi_mask arch_send_call_function_ipi_mask #endif /* !ASSEMBLY */ diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 9995d7e..ba9b680 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -214,11 +214,11 @@ ipi_send(int cpu, enum ipi_message_type op) } static void -send_IPI_mask(cpumask_t mask, enum ipi_message_type op) +send_IPI_mask(const struct cpumask *mask, enum ipi_message_type op) { int cpu; - for_each_cpu_mask(cpu, mask) + for_each_cpu(cpu, mask) ipi_send(cpu, op); } @@ -257,7 +257,7 @@ smp_send_all_nop(void) send_IPI_allbutself(IPI_NOP); } -void arch_send_call_function_ipi(cpumask_t mask) +void arch_send_call_function_ipi_mask(const struct cpumask *mask) { send_IPI_mask(mask, IPI_CALL_FUNC); } -- cgit v0.10.2 From bd071e1a371d31db243edc4714ff9e8d1ea1309e Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 16 Mar 2009 14:19:37 +1030 Subject: cpumask: prepare for iterators to only go to nr_cpu_ids/nr_cpumask_bits.: parisc Impact: cleanup, futureproof In fact, all cpumask ops will only be valid (in general) for bit numbers < nr_cpu_ids. So use that instead of NR_CPUS in various places. This is always safe: no cpu number can be >= nr_cpu_ids, and nr_cpu_ids is initialized to NR_CPUS at boot. Signed-off-by: Rusty Russell Signed-off-by: Mike Travis Acked-by: Ingo Molnar diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index 29e70e1..103752a 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -311,12 +311,12 @@ unsigned long txn_alloc_addr(unsigned int virt_irq) next_cpu++; /* assign to "next" CPU we want this bugger on */ /* validate entry */ - while ((next_cpu < NR_CPUS) && + while ((next_cpu < nr_cpu_ids) && (!per_cpu(cpu_data, next_cpu).txn_addr || !cpu_online(next_cpu))) next_cpu++; - if (next_cpu >= NR_CPUS) + if (next_cpu >= nr_cpu_ids) next_cpu = 0; /* nothing else, assign monarch */ return txn_affinity_addr(virt_irq, next_cpu); diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c index ecb6093..44a1a50 100644 --- a/arch/parisc/kernel/processor.c +++ b/arch/parisc/kernel/processor.c @@ -100,8 +100,8 @@ static int __cpuinit processor_probe(struct parisc_device *dev) struct cpuinfo_parisc *p; #ifdef CONFIG_SMP - if (num_online_cpus() >= NR_CPUS) { - printk(KERN_INFO "num_online_cpus() >= NR_CPUS\n"); + if (num_online_cpus() >= nr_cpu_ids) { + printk(KERN_INFO "num_online_cpus() >= nr_cpu_ids\n"); return 1; } #else -- cgit v0.10.2 From 9bc181d8d7cb6462de0c315e364780ad275f7c57 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 16 Mar 2009 14:19:38 +1030 Subject: cpumask: Use accessors code.: parisc Impact: use new API Use the accessors rather than frobbing bits directly. Most of this is in arch code I haven't even compiled, but it is mostly straightforward. Signed-off-by: Rusty Russell Signed-off-by: Mike Travis diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c index 44a1a50..bdbabfb 100644 --- a/arch/parisc/kernel/processor.c +++ b/arch/parisc/kernel/processor.c @@ -214,7 +214,7 @@ static int __cpuinit processor_probe(struct parisc_device *dev) */ #ifdef CONFIG_SMP if (cpuid) { - cpu_set(cpuid, cpu_present_map); + set_cpu_present(cpuid, true); cpu_up(cpuid); } #endif diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index ba9b680..8691979 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -113,7 +113,7 @@ halt_processor(void) { /* REVISIT : redirect I/O Interrupts to another CPU? */ /* REVISIT : does PM *know* this CPU isn't available? */ - cpu_clear(smp_processor_id(), cpu_online_map); + set_cpu_online(smp_processor_id(), false); local_irq_disable(); for (;;) ; @@ -296,13 +296,14 @@ smp_cpu_init(int cpunum) mb(); /* Well, support 2.4 linux scheme as well. */ - if (cpu_test_and_set(cpunum, cpu_online_map)) + if (cpu_isset(cpunum, cpu_online_map)) { extern void machine_halt(void); /* arch/parisc.../process.c */ printk(KERN_CRIT "CPU#%d already initialized!\n", cpunum); machine_halt(); } + set_cpu_online(cpunum, true); /* Initialise the idle task for this CPU */ atomic_inc(&init_mm.mm_count); @@ -424,8 +425,8 @@ void __init smp_prepare_boot_cpu(void) /* Setup BSP mappings */ printk(KERN_INFO "SMP: bootstrap CPU ID is %d\n", bootstrap_processor); - cpu_set(bootstrap_processor, cpu_online_map); - cpu_set(bootstrap_processor, cpu_present_map); + set_cpu_online(bootstrap_processor, true); + set_cpu_present(bootstrap_processor, true); } @@ -436,8 +437,7 @@ void __init smp_prepare_boot_cpu(void) */ void __init smp_prepare_cpus(unsigned int max_cpus) { - cpus_clear(cpu_present_map); - cpu_set(0, cpu_present_map); + init_cpu_present(cpumask_of(0)); parisc_max_cpus = max_cpus; if (!max_cpus) -- cgit v0.10.2 From 48d27cb2299c0b2fc4d551bddb6a1005828dc0c6 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sun, 18 Jan 2009 19:16:16 +0100 Subject: parisc: fix usage of 32bit PTE page table entries on 32bit kernels This patch fixes a long outstanding bug on 32bit parisc linux kernels which prevented us from using 32bit PTE table entries (instead of 64bit entries of which 32bit were unused). The problem was caused by this assembler statement in the L2_ptep macro in arch/parisc/kernel/entry.S:447: EXTR \va,31-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index which expanded to extrw,u r8,9,11,r1 and which has undefined behavior since the length value (11) extends beyond the leftmost bit (11-1 > 9). Interestingly PA2.0 processors seem to don't care and just zero-extend the value, while PA1.1 processors don't. Fix this problem by detecting an address space overflow with ASM_BITS_PER_PGD and adjusting it accordingly. To prevent such problems in the future, some compile time sanity checks in arch/parisc/mm/init.c were added. Since the page table now only consumes half of it's old size, we can use the freed memory to harmonize 32- and 64bit kernels and let both map 16MB for the initial page table. Signed-off-by: Helge Deller Signed-off-by: Kyle McMartin diff --git a/arch/parisc/include/asm/page.h b/arch/parisc/include/asm/page.h index c3941f0..7bc5125 100644 --- a/arch/parisc/include/asm/page.h +++ b/arch/parisc/include/asm/page.h @@ -36,16 +36,7 @@ void clear_user_page(void *page, unsigned long vaddr, struct page *pg); */ #define STRICT_MM_TYPECHECKS #ifdef STRICT_MM_TYPECHECKS -typedef struct { unsigned long pte; -#if !defined(CONFIG_64BIT) - unsigned long future_flags; - /* XXX: it's possible to remove future_flags and change BITS_PER_PTE_ENTRY - to 2, but then strangely the identical 32bit kernel boots on a - c3000(pa20), but not any longer on a 715(pa11). - Still investigating... HelgeD. - */ -#endif -} pte_t; /* either 32 or 64bit */ +typedef struct { unsigned long pte; } pte_t; /* either 32 or 64bit */ /* NOTE: even on 64 bits, these entries are __u32 because we allocate * the pmd and pgd in ZONE_DMA (i.e. under 4GB) */ @@ -111,7 +102,7 @@ extern int npmem_ranges; #define BITS_PER_PMD_ENTRY 2 #define BITS_PER_PGD_ENTRY 2 #else -#define BITS_PER_PTE_ENTRY 3 +#define BITS_PER_PTE_ENTRY 2 #define BITS_PER_PMD_ENTRY 2 #define BITS_PER_PGD_ENTRY BITS_PER_PMD_ENTRY #endif diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h index 470a4b8..a27d2e2 100644 --- a/arch/parisc/include/asm/pgtable.h +++ b/arch/parisc/include/asm/pgtable.h @@ -50,11 +50,7 @@ printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, (unsigned long)pgd_val(e)) /* This is the size of the initially mapped kernel memory */ -#ifdef CONFIG_64BIT #define KERNEL_INITIAL_ORDER 24 /* 0 to 1<<24 = 16MB */ -#else -#define KERNEL_INITIAL_ORDER 23 /* 0 to 1<<23 = 8MB */ -#endif #define KERNEL_INITIAL_SIZE (1 << KERNEL_INITIAL_ORDER) #if defined(CONFIG_64BIT) && defined(CONFIG_PARISC_PAGE_SIZE_4KB) @@ -91,16 +87,25 @@ /* Definitions for 1st level */ #define PGDIR_SHIFT (PMD_SHIFT + BITS_PER_PMD) +#if (PGDIR_SHIFT + PAGE_SHIFT + PGD_ORDER - BITS_PER_PGD_ENTRY) > BITS_PER_LONG +#define BITS_PER_PGD (BITS_PER_LONG - PGDIR_SHIFT) +#else #define BITS_PER_PGD (PAGE_SHIFT + PGD_ORDER - BITS_PER_PGD_ENTRY) +#endif #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) #define PTRS_PER_PGD (1UL << BITS_PER_PGD) #define USER_PTRS_PER_PGD PTRS_PER_PGD +#ifdef CONFIG_64BIT #define MAX_ADDRBITS (PGDIR_SHIFT + BITS_PER_PGD) #define MAX_ADDRESS (1UL << MAX_ADDRBITS) - #define SPACEID_SHIFT (MAX_ADDRBITS - 32) +#else +#define MAX_ADDRBITS (BITS_PER_LONG) +#define MAX_ADDRESS (1UL << MAX_ADDRBITS) +#define SPACEID_SHIFT 0 +#endif /* This calculates the number of initial pages we need for the initial * page tables */ diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 9d704d9..4356ceb 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -456,6 +456,13 @@ void __init mem_init(void) { int codesize, reservedpages, datasize, initsize; + /* Do sanity checks on page table constants */ + BUILD_BUG_ON(PTE_ENTRY_SIZE != sizeof(pte_t)); + BUILD_BUG_ON(PMD_ENTRY_SIZE != sizeof(pmd_t)); + BUILD_BUG_ON(PGD_ENTRY_SIZE != sizeof(pgd_t)); + BUILD_BUG_ON(PAGE_SHIFT + BITS_PER_PTE + BITS_PER_PMD + BITS_PER_PGD + > BITS_PER_LONG); + high_memory = __va((max_pfn << PAGE_SHIFT)); #ifndef CONFIG_DISCONTIGMEM -- cgit v0.10.2 From 1152a68c4226ce48c95241b6ffc543850b4b3a97 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sun, 18 Jan 2009 19:30:18 +0100 Subject: parisc: use constants instead of numbers in assembly A few small fixups: * _PAGE_SIZE_ENCODING_DEFAULT is wrong here, as one might assume that it's possible to define the page size that way. This is wrong. Use 0 instead. * use constants instead of hardcoded numerical values in depi and extru while building the PFN out of the pte entry * use SHRREG instead of extru (iitlba expects the PFN at bits {7..26}) Still wondering why we can use the same register (pte) as extru source and target register, but it seems to work on PA1.1 and PA2.0... Signed-off-by: Helge Deller Signed-off-by: Kyle McMartin diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 0db9fdc..0f7ff93 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -563,8 +563,8 @@ /* Get rid of prot bits and convert to page addr for iitlba */ - depi _PAGE_SIZE_ENCODING_DEFAULT,31,ASM_PFN_PTE_SHIFT,\pte - extru \pte,24,25,\pte + depi 0,31,ASM_PFN_PTE_SHIFT,\pte + SHRREG \pte,(ASM_PFN_PTE_SHIFT-(31-26)),\pte .endm /* This is for ILP32 PA2.0 only. The TLB insertion needs @@ -1337,8 +1337,8 @@ nadtlb_check_flush_11: /* Get rid of prot bits and convert to page addr for idtlba */ - depi 0,31,12,pte - extru pte,24,25,pte + depi 0,31,ASM_PFN_PTE_SHIFT,pte + SHRREG pte,(ASM_PFN_PTE_SHIFT-(31-26)),pte mfsp %sr1,t0 /* Save sr1 so we can use it in tlb inserts */ mtsp spc,%sr1 -- cgit v0.10.2 From 445c088f88d63db49598390be3525252d211688f Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 30 Jan 2009 01:03:50 +0000 Subject: parisc: expose 32/64-bit capabilities in cpuinfo It'd be rather useful for debian-installer if we could get hold of accurate firmware information on whether only 32-bit kernels are supported, only 64-bit kernels, or both; this would allow us to present an accurate menu of kernel packages if more than one is available, rather than the user having to guess. This patch attempts to expose it in cpuinfo. I adjusted pdc_model_capabilities to cope with a potential PDC_INVALID_ARG return as the firmware manual instructs, by assuming 32-bit only. This may be the wrong place for it. I made up user-visible capability names by total fiat and for the moment ignored the other bits that may appear in the capabilities word. I have no PA-RISC machine myself to test on, and no PA experience either, so I rather hope that somebody will kind-heartedly take this and fix it up if needed. I ran it past Dann Frazier on IRC and he said "looks good to me", but I think without testing. Also, this is against the Ubuntu 2.6.28 kernel tree since that's what I had handy and I was a bit tight on disk space to slurp down another tree. Sorry if it's skewed in any relevant way; I'll be happy to adjust if necessary. Thanks in advance! Signed-off-by: Colin Watson Signed-off-by: Kyle McMartin diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h index 430f1ae..a26e98d 100644 --- a/arch/parisc/include/asm/pdc.h +++ b/arch/parisc/include/asm/pdc.h @@ -49,6 +49,8 @@ #define PDC_MODEL_CPU_ID 6 /* returns cpu-id (only newer machines!) */ #define PDC_MODEL_CAPABILITIES 7 /* returns OS32/OS64-flags */ /* Values for PDC_MODEL_CAPABILITIES non-equivalent virtual aliasing support */ +#define PDC_MODEL_OS64 (1 << 0) +#define PDC_MODEL_OS32 (1 << 1) #define PDC_MODEL_IOPDIR_FDC (1 << 2) #define PDC_MODEL_NVA_MASK (3 << 4) #define PDC_MODEL_NVA_SUPPORTED (0 << 4) diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index f6d2412..4c247e0 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c @@ -527,7 +527,11 @@ int pdc_model_capabilities(unsigned long *capabilities) pdc_result[0] = 0; /* preset zero (call may not be implemented!) */ retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, __pa(pdc_result), 0); convert_to_wide(pdc_result); - *capabilities = pdc_result[0]; + if (retval == PDC_OK) { + *capabilities = pdc_result[0]; + } else { + *capabilities = PDC_MODEL_OS32; + } spin_unlock_irqrestore(&pdc_lock, flags); return retval; diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c index ecb6093..df5e28c 100644 --- a/arch/parisc/kernel/processor.c +++ b/arch/parisc/kernel/processor.c @@ -364,6 +364,13 @@ show_cpuinfo (struct seq_file *m, void *v) boot_cpu_data.cpu_hz / 1000000, boot_cpu_data.cpu_hz % 1000000 ); + seq_printf(m, "capabilities\t:"); + if (boot_cpu_data.pdc.capabilities & PDC_MODEL_OS32) + seq_printf(m, " os32"); + if (boot_cpu_data.pdc.capabilities & PDC_MODEL_OS64) + seq_printf(m, " os64"); + seq_printf(m, "\n"); + seq_printf(m, "model\t\t: %s\n" "model name\t: %s\n", boot_cpu_data.pdc.sys_model_name, -- cgit v0.10.2 From afca2523876301cc6130fc3cc402173eeeb89830 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Thu, 5 Feb 2009 00:06:00 +0100 Subject: parisc: allow to build with 16k default kernel page size Introduce new convert_for_tlb_insert20 macro and use it to replace assembler statements with hardcoded constants. This change allows the parisc64 kernel to boot with 16kb default kernel page size, aka CONFIG_PARISC_PAGE_SIZE_16KB=y. Signed-off-by: Helge Deller Signed-off-by: Kyle McMartin diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 0f7ff93..4e9dd15 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -505,6 +505,18 @@ STREG \pte,0(\ptep) .endm + /* bitshift difference between a PFN (based on kernel's PAGE_SIZE) + * to a CPU TLB 4k PFN (4k => 12 bits to shift) */ + #define PAGE_ADD_SHIFT (PAGE_SHIFT-12) + + /* Drop prot bits and convert to page addr for iitlbt and idtlbt */ + .macro convert_for_tlb_insert20 pte + extrd,u \pte,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\ + 64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte + depdi _PAGE_SIZE_ENCODING_DEFAULT,63,\ + (63-58)+PAGE_ADD_SHIFT,\pte + .endm + /* Convert the pte and prot to tlb insertion values. How * this happens is quite subtle, read below */ .macro make_insert_tlb spc,pte,prot @@ -544,8 +556,7 @@ depi 1,12,1,\prot /* Drop prot bits and convert to page addr for iitlbt and idtlbt */ - extrd,u \pte,(63-ASM_PFN_PTE_SHIFT)+(63-58),64-PAGE_SHIFT,\pte - depdi _PAGE_SIZE_ENCODING_DEFAULT,63,63-58,\pte + convert_for_tlb_insert20 \pte .endm /* Identical macro to make_insert_tlb above, except it @@ -1244,10 +1255,9 @@ nadtlb_check_flush_20w: depdi,z 7,7,3,prot depdi 1,10,1,prot - /* Get rid of prot bits and convert to page addr for idtlbt */ + /* Drop prot bits from pte and convert to page addr for idtlbt */ + convert_for_tlb_insert20 pte - depdi 0,63,12,pte - extrd,u pte,56,52,pte idtlbt pte,prot rfir @@ -1403,10 +1413,9 @@ nadtlb_check_flush_20: depdi,z 7,7,3,prot depdi 1,10,1,prot - /* Get rid of prot bits and convert to page addr for idtlbt */ + /* Drop prot bits from pte and convert to page addr for idtlbt */ + convert_for_tlb_insert20 pte - depdi 0,63,12,pte - extrd,u pte,56,32,pte idtlbt pte,prot rfir -- cgit v0.10.2 From 548f1176f0ac637eff895defb715ce6fde7c460a Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Fri, 6 Feb 2009 21:50:39 +0100 Subject: parisc: add LATENCYTOP_SUPPORT and CONFIG_STACKTRACE_SUPPORT Signed-off-by: Helge Deller Signed-off-by: Kyle McMartin diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index aacf11d..4866e2f 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -75,6 +75,9 @@ config GENERIC_HARDIRQS config GENERIC_IRQ_PROBE def_bool y +config HAVE_LATENCYTOP_SUPPORT + def_bool y + config IRQ_PER_CPU bool default y @@ -83,6 +86,9 @@ config IRQ_PER_CPU config PM bool +config STACKTRACE_SUPPORT + def_bool y + config ISA_DMA_API bool diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile index 016d3fc..a7ba8cd 100644 --- a/arch/parisc/kernel/Makefile +++ b/arch/parisc/kernel/Makefile @@ -16,5 +16,6 @@ obj-$(CONFIG_PA11) += pci-dma.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_64BIT) += binfmt_elf32.o sys_parisc32.o signal32.o +obj-$(CONFIG_STACKTRACE)+= stacktrace.o # only supported for PCX-W/U in 64-bit mode at the moment obj-$(CONFIG_64BIT) += perf.o perf_asm.o diff --git a/arch/parisc/kernel/stacktrace.c b/arch/parisc/kernel/stacktrace.c new file mode 100644 index 0000000..2fe914c --- /dev/null +++ b/arch/parisc/kernel/stacktrace.c @@ -0,0 +1,63 @@ +/* + * Stack trace management functions + * + * Copyright (C) 2009 Helge Deller + * based on arch/x86/kernel/stacktrace.c by Ingo Molnar + * and parisc unwind functions by Randolph Chung + * + * TODO: Userspace stacktrace (CONFIG_USER_STACKTRACE_SUPPORT) + */ +#include +#include + +#include + +static void dump_trace(struct task_struct *task, struct stack_trace *trace) +{ + struct unwind_frame_info info; + + /* initialize unwind info */ + if (task == current) { + unsigned long sp; + struct pt_regs r; +HERE: + asm volatile ("copy %%r30, %0" : "=r"(sp)); + memset(&r, 0, sizeof(struct pt_regs)); + r.iaoq[0] = (unsigned long)&&HERE; + r.gr[2] = (unsigned long)__builtin_return_address(0); + r.gr[30] = sp; + unwind_frame_init(&info, task, &r); + } else { + unwind_frame_init_from_blocked_task(&info, task); + } + + /* unwind stack and save entries in stack_trace struct */ + trace->nr_entries = 0; + while (trace->nr_entries < trace->max_entries) { + if (unwind_once(&info) < 0 || info.ip == 0) + break; + + if (__kernel_text_address(info.ip)) + trace->entries[trace->nr_entries++] = info.ip; + } +} + + +/* + * Save stack-backtrace addresses into a stack_trace buffer. + */ +void save_stack_trace(struct stack_trace *trace) +{ + dump_trace(current, trace); + if (trace->nr_entries < trace->max_entries) + trace->entries[trace->nr_entries++] = ULONG_MAX; +} +EXPORT_SYMBOL_GPL(save_stack_trace); + +void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) +{ + dump_trace(tsk, trace); + if (trace->nr_entries < trace->max_entries) + trace->entries[trace->nr_entries++] = ULONG_MAX; +} +EXPORT_SYMBOL_GPL(save_stack_trace_tsk); -- cgit v0.10.2 From 803094f480aa5b7dd5187a17e6e60ff24721c212 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Fri, 13 Feb 2009 23:58:29 +0100 Subject: parisc: simplify sys_clone() No need to test clone_flags here and set parent_tidptr and child_tidptr accordingly. The same check will be done in do_fork() and copy_process() anyway. Signed-off-by: Helge Deller Signed-off-by: Kyle McMartin diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index b80e02a..ad585fd 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -231,8 +231,8 @@ sys_clone(unsigned long clone_flags, unsigned long usp, However, these last 3 args are only examined if the proper flags are set. */ - int __user *child_tidptr; - int __user *parent_tidptr; + int __user *parent_tidptr = (int __user *)regs->gr[24]; + int __user *child_tidptr = (int __user *)regs->gr[22]; /* usp must be word aligned. This also prevents users from * passing in the value 1 (which is the signal for a special @@ -243,16 +243,6 @@ sys_clone(unsigned long clone_flags, unsigned long usp, if (usp == 0) usp = regs->gr[30]; - if (clone_flags & CLONE_PARENT_SETTID) - parent_tidptr = (int __user *)regs->gr[24]; - else - parent_tidptr = NULL; - - if (clone_flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) - child_tidptr = (int __user *)regs->gr[22]; - else - child_tidptr = NULL; - return do_fork(clone_flags, usp, regs, 0, parent_tidptr, child_tidptr); } -- cgit v0.10.2 From d75f054a2cf0614ff63d534ff21ca8eaab41e713 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Mon, 9 Feb 2009 00:43:36 +0100 Subject: parisc: add ftrace (function and graph tracer) functionality This patch adds the ftrace debugging functionality to the parisc kernel. It will currently only work with 64bit kernels, because the gcc options -pg and -ffunction-sections can't be enabled at the same time and -ffunction-sections is still needed to be able to link 32bit kernels. Signed-off-by: Helge Deller Signed-off-by: Kyle McMartin diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 4866e2f..7fd696f 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -9,6 +9,9 @@ config PARISC def_bool y select HAVE_IDE select HAVE_OPROFILE + select HAVE_FUNCTION_TRACER if 64BIT + select HAVE_FUNCTION_GRAPH_TRACER if 64BIT + select HAVE_FUNCTION_TRACE_MCOUNT_TEST if 64BIT select RTC_CLASS select RTC_DRV_PARISC select INIT_ALL_POSSIBLE diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index 0d42827..da6f669 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile @@ -56,7 +56,9 @@ cflags-y += -mdisable-fpregs # Without this, "ld -r" results in .text sections that are too big # (> 0x40000) for branches to reach stubs. -cflags-y += -ffunction-sections +ifndef CONFIG_FUNCTION_TRACER + cflags-y += -ffunction-sections +endif # select which processor to optimise for cflags-$(CONFIG_PA7100) += -march=1.1 -mschedule=7100 diff --git a/arch/parisc/include/asm/ftrace.h b/arch/parisc/include/asm/ftrace.h new file mode 100644 index 0000000..2fa05dd --- /dev/null +++ b/arch/parisc/include/asm/ftrace.h @@ -0,0 +1,25 @@ +#ifndef _ASM_PARISC_FTRACE_H +#define _ASM_PARISC_FTRACE_H + +#ifndef __ASSEMBLY__ +extern void mcount(void); + +/* + * Stack of return addresses for functions of a thread. + * Used in struct thread_info + */ +struct ftrace_ret_stack { + unsigned long ret; + unsigned long func; + unsigned long long calltime; +}; + +/* + * Primary handler of a function return. + * It relays on ftrace_return_to_handler. + * Defined in entry.S + */ +extern void return_to_handler(void); +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_PARISC_FTRACE_H */ diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile index a7ba8cd..67db072 100644 --- a/arch/parisc/kernel/Makefile +++ b/arch/parisc/kernel/Makefile @@ -11,6 +11,18 @@ obj-y := cache.o pacache.o setup.o traps.o time.o irq.o \ process.o processor.o pdc_cons.o pdc_chassis.o unwind.o \ topology.o +ifdef CONFIG_FUNCTION_TRACER +# Do not profile debug and lowlevel utilities +CFLAGS_REMOVE_ftrace.o = -pg +CFLAGS_REMOVE_cache.o = -pg +CFLAGS_REMOVE_irq.o = -pg +CFLAGS_REMOVE_pacache.o = -pg +CFLAGS_REMOVE_perf.o = -pg +CFLAGS_REMOVE_traps.o = -pg +CFLAGS_REMOVE_unaligned.o = -pg +CFLAGS_REMOVE_unwind.o = -pg +endif + obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_PA11) += pci-dma.o obj-$(CONFIG_PCI) += pci.o @@ -19,3 +31,5 @@ obj-$(CONFIG_64BIT) += binfmt_elf32.o sys_parisc32.o signal32.o obj-$(CONFIG_STACKTRACE)+= stacktrace.o # only supported for PCX-W/U in 64-bit mode at the moment obj-$(CONFIG_64BIT) += perf.o perf_asm.o +obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o +obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 4e9dd15..ae3e70cd 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -2185,6 +2185,33 @@ syscall_do_resched: ENDPROC(syscall_exit) +#ifdef CONFIG_FUNCTION_TRACER + .import ftrace_function_trampoline,code +ENTRY(_mcount) + copy %r3, %arg2 + b ftrace_function_trampoline + nop +ENDPROC(_mcount) + +ENTRY(return_to_handler) + load32 return_trampoline, %rp + copy %ret0, %arg0 + copy %ret1, %arg1 + b ftrace_return_to_handler + nop +return_trampoline: + copy %ret0, %rp + copy %r23, %ret0 + copy %r24, %ret1 + +.globl ftrace_stub +ftrace_stub: + bv %r0(%rp) + nop +ENDPROC(return_to_handler) +#endif /* CONFIG_FUNCTION_TRACER */ + + get_register: /* * get_register is used by the non access tlb miss handlers to diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c new file mode 100644 index 0000000..9877372 --- /dev/null +++ b/arch/parisc/kernel/ftrace.c @@ -0,0 +1,185 @@ +/* + * Code for tracing calls in Linux kernel. + * Copyright (C) 2009 Helge Deller + * + * based on code for x86 which is: + * Copyright (C) 2007-2008 Steven Rostedt + * + * future possible enhancements: + * - add CONFIG_DYNAMIC_FTRACE + * - add CONFIG_STACK_TRACER + */ + +#include +#include + +#include +#include + + + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + +/* Add a function return address to the trace stack on thread info.*/ +static int push_return_trace(unsigned long ret, unsigned long long time, + unsigned long func, int *depth) +{ + int index; + + if (!current->ret_stack) + return -EBUSY; + + /* The return trace stack is full */ + if (current->curr_ret_stack == FTRACE_RETFUNC_DEPTH - 1) { + atomic_inc(¤t->trace_overrun); + return -EBUSY; + } + + index = ++current->curr_ret_stack; + barrier(); + current->ret_stack[index].ret = ret; + current->ret_stack[index].func = func; + current->ret_stack[index].calltime = time; + *depth = index; + + return 0; +} + +/* Retrieve a function return address to the trace stack on thread info.*/ +static void pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret) +{ + int index; + + index = current->curr_ret_stack; + + if (unlikely(index < 0)) { + ftrace_graph_stop(); + WARN_ON(1); + /* Might as well panic, otherwise we have no where to go */ + *ret = (unsigned long) + dereference_function_descriptor(&panic); + return; + } + + *ret = current->ret_stack[index].ret; + trace->func = current->ret_stack[index].func; + trace->calltime = current->ret_stack[index].calltime; + trace->overrun = atomic_read(¤t->trace_overrun); + trace->depth = index; + barrier(); + current->curr_ret_stack--; + +} + +/* + * Send the trace to the ring-buffer. + * @return the original return address. + */ +unsigned long ftrace_return_to_handler(unsigned long retval0, + unsigned long retval1) +{ + struct ftrace_graph_ret trace; + unsigned long ret; + + pop_return_trace(&trace, &ret); + trace.rettime = cpu_clock(raw_smp_processor_id()); + ftrace_graph_return(&trace); + + if (unlikely(!ret)) { + ftrace_graph_stop(); + WARN_ON(1); + /* Might as well panic. What else to do? */ + ret = (unsigned long) + dereference_function_descriptor(&panic); + } + + /* HACK: we hand over the old functions' return values + in %r23 and %r24. Assembly in entry.S will take care + and move those to their final registers %ret0 and %ret1 */ + asm( "copy %0, %%r23 \n\t" + "copy %1, %%r24 \n" : : "r" (retval0), "r" (retval1) ); + + return ret; +} + +/* + * Hook the return address and push it in the stack of return addrs + * in current thread info. + */ +void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) +{ + unsigned long old; + unsigned long long calltime; + struct ftrace_graph_ent trace; + + if (unlikely(atomic_read(¤t->tracing_graph_pause))) + return; + + old = *parent; + *parent = (unsigned long) + dereference_function_descriptor(&return_to_handler); + + if (unlikely(!__kernel_text_address(old))) { + ftrace_graph_stop(); + *parent = old; + WARN_ON(1); + return; + } + + calltime = cpu_clock(raw_smp_processor_id()); + + if (push_return_trace(old, calltime, + self_addr, &trace.depth) == -EBUSY) { + *parent = old; + return; + } + + trace.func = self_addr; + + /* Only trace if the calling function expects to */ + if (!ftrace_graph_entry(&trace)) { + current->curr_ret_stack--; + *parent = old; + } +} + +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ + + +void ftrace_function_trampoline(unsigned long parent, + unsigned long self_addr, + unsigned long org_sp_gr3) +{ + extern ftrace_func_t ftrace_trace_function; + + if (function_trace_stop) + return; + + if (ftrace_trace_function != ftrace_stub) { + ftrace_trace_function(parent, self_addr); + return; + } +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + if (ftrace_graph_entry && ftrace_graph_return) { + unsigned long sp; + unsigned long *parent_rp; + + asm volatile ("copy %%r30, %0" : "=r"(sp)); + /* sanity check: is stack pointer which we got from + assembler function in entry.S in a reasonable + range compared to current stack pointer? */ + if ((sp - org_sp_gr3) > 0x400) + return; + + /* calculate pointer to %rp in stack */ + parent_rp = (unsigned long *) org_sp_gr3 - 0x10; + /* sanity check: parent_rp should hold parent */ + if (*parent_rp != parent) + return; + + prepare_ftrace_return(parent_rp, self_addr); + return; + } +#endif +} + diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c index 0eecfbb..df65366 100644 --- a/arch/parisc/kernel/parisc_ksyms.c +++ b/arch/parisc/kernel/parisc_ksyms.c @@ -153,5 +153,10 @@ EXPORT_SYMBOL(node_data); EXPORT_SYMBOL(pfnnid_map); #endif +#ifdef CONFIG_FUNCTION_TRACER +extern void _mcount(void); +EXPORT_SYMBOL(_mcount); +#endif + /* from pacache.S -- needed for copy_page */ EXPORT_SYMBOL(copy_user_page_asm); diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 9995d7e..8545f2e 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -120,7 +121,7 @@ halt_processor(void) } -irqreturn_t +irqreturn_t __irq_entry ipi_interrupt(int irq, void *dev_id) { int this_cpu = smp_processor_id(); diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 9d46c43..badaad9 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -53,7 +54,7 @@ static unsigned long clocktick __read_mostly; /* timer cycles per tick */ * held off for an arbitrarily long period of time by interrupts being * disabled, so we may miss one or more ticks. */ -irqreturn_t timer_interrupt(int irq, void *dev_id) +irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id) { unsigned long now; unsigned long next_tick; diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index ba658d2..7bf122a 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -494,7 +494,7 @@ void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long o panic(msg); } -void handle_interruption(int code, struct pt_regs *regs) +void notrace handle_interruption(int code, struct pt_regs *regs) { unsigned long fault_address = 0; unsigned long fault_space = 0; diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S index 1a3b6cc..fd2cc4f 100644 --- a/arch/parisc/kernel/vmlinux.lds.S +++ b/arch/parisc/kernel/vmlinux.lds.S @@ -54,6 +54,8 @@ SECTIONS TEXT_TEXT SCHED_TEXT LOCK_TEXT + KPROBES_TEXT + IRQENTRY_TEXT *(.text.do_softirq) *(.text.sys_exit) *(.text.do_sigaltstack) -- cgit v0.10.2 From 8a1def457bab9f9654bd4dbb1e3eea6fedd26afa Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 6 Jan 2009 14:23:13 +0100 Subject: parisc: blink all or loadavg LEDs on oops - depending on machine type, blink all leds or just the loadavg leds twice a second on oops. - cancel_rearming_delayed_workqueue() is obsolete, use cancel_delayed_work_sync() instead Signed-off-by: Helge Deller Signed-off-by: Kyle McMartin diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c index 454b653..75ff6d7 100644 --- a/drivers/parisc/led.c +++ b/drivers/parisc/led.c @@ -3,7 +3,7 @@ * * (c) Copyright 2000 Red Hat Software * (c) Copyright 2000 Helge Deller - * (c) Copyright 2001-2005 Helge Deller + * (c) Copyright 2001-2009 Helge Deller * (c) Copyright 2001 Randolph Chung * * This program is free software; you can redistribute it and/or modify @@ -463,9 +463,20 @@ static void led_work_func (struct work_struct *unused) if (likely(led_lanrxtx)) currentleds |= led_get_net_activity(); if (likely(led_diskio)) currentleds |= led_get_diskio_activity(); - /* blink all LEDs twice a second if we got an Oops (HPMC) */ - if (unlikely(oops_in_progress)) - currentleds = (count_HZ<=(HZ/2)) ? 0 : 0xff; + /* blink LEDs if we got an Oops (HPMC) */ + if (unlikely(oops_in_progress)) { + if (boot_cpu_data.cpu_type >= pcxl2) { + /* newer machines don't have loadavg. LEDs, so we + * let all LEDs blink twice per second instead */ + currentleds = (count_HZ <= (HZ/2)) ? 0 : 0xff; + } else { + /* old machines: blink loadavg. LEDs twice per second */ + if (count_HZ <= (HZ/2)) + currentleds &= ~(LED4|LED5|LED6|LED7); + else + currentleds |= (LED4|LED5|LED6|LED7); + } + } if (currentleds != lastleds) { @@ -511,7 +522,7 @@ static int led_halt(struct notifier_block *nb, unsigned long event, void *buf) /* Cancel the work item and delete the queue */ if (led_wq) { - cancel_rearming_delayed_workqueue(led_wq, &led_task); + cancel_delayed_work_sync(&led_task); destroy_workqueue(led_wq); led_wq = NULL; } @@ -630,7 +641,7 @@ int lcd_print( const char *str ) /* temporarily disable the led work task */ if (led_wq) - cancel_rearming_delayed_workqueue(led_wq, &led_task); + cancel_delayed_work_sync(&led_task); /* copy display string to buffer for procfs */ strlcpy(lcd_text, str, sizeof(lcd_text)); -- cgit v0.10.2 From c84c3a698f17ae5d55a6ecc76298fb894e106336 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 30 Dec 2008 02:47:38 +0000 Subject: parisc: document light weight syscall ABI Document the LWS ABI including implementation notes for userspace, and comment cleanup. Remove extraneous .align 16 after lws_lock_start. Signed-off-by: Carlos O'Donell Signed-off-by: Helge Deller Signed-off-by: Kyle McMartin diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 69b6eeb..59fc1a43 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -365,17 +365,51 @@ tracesys_sigexit: /********************************************************* - Light-weight-syscall code + 32/64-bit Light-Weight-Syscall ABI - r20 - lws number - r26,r25,r24,r23,r22 - Input registers - r28 - Function return register - r21 - Error code. + * - Indicates a hint for userspace inline asm + implementations. - Scracth: Any of the above that aren't being - currently used, including r1. + Syscall number (caller-saves) + - %r20 + * In asm clobber. - Return pointer: r31 (Not usable) + Argument registers (caller-saves) + - %r26, %r25, %r24, %r23, %r22 + * In asm input. + + Return registers (caller-saves) + - %r28 (return), %r21 (errno) + * In asm output. + + Caller-saves registers + - %r1, %r27, %r29 + - %r2 (return pointer) + - %r31 (ble link register) + * In asm clobber. + + Callee-saves registers + - %r3-%r18 + - %r30 (stack pointer) + * Not in asm clobber. + + If userspace is 32-bit: + Callee-saves registers + - %r19 (32-bit PIC register) + + Differences from 32-bit calling convention: + - Syscall number in %r20 + - Additional argument register %r22 (arg4) + - Callee-saves %r19. + + If userspace is 64-bit: + Callee-saves registers + - %r27 (64-bit PIC register) + + Differences from 64-bit calling convention: + - Syscall number in %r20 + - Additional argument register %r22 (arg4) + - Callee-saves %r27. Error codes returned by entry path: @@ -473,7 +507,8 @@ lws_compare_and_swap64: b,n lws_compare_and_swap #else /* If we are not a 64-bit kernel, then we don't - * implement having 64-bit input registers + * have 64-bit input registers, and calling + * the 64-bit LWS CAS returns ENOSYS. */ b,n lws_exit_nosys #endif @@ -635,12 +670,15 @@ END(sys_call_table64) /* All light-weight-syscall atomic operations will use this set of locks + + NOTE: The lws_lock_start symbol must be + at least 16-byte aligned for safe use + with ldcw. */ .section .data .align PAGE_SIZE ENTRY(lws_lock_start) /* lws locks */ - .align 16 .rept 16 /* Keep locks aligned at 16-bytes */ .word 1 -- cgit v0.10.2 From c48faf86b0d59cc43ff4eede59c4af7afbd7c0ff Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Mon, 16 Feb 2009 03:03:11 +0000 Subject: parisc: oops_enter()/oops_exit() in die() As pointed out by Russell in http://marc.info/?l=linux-arch&m=118208089204630&w=2 Signed-off-by: Helge Deller Signed-off-by: Kyle McMartin diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index 7bf122a..c32f5d6 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -247,6 +247,8 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err) oops_in_progress = 1; + oops_enter(); + /* Amuse the user in a SPARC fashion */ if (err) printk( KERN_CRIT " _______________________________ \n" @@ -293,6 +295,7 @@ KERN_CRIT " || ||\n"); panic("Fatal exception"); } + oops_exit(); do_exit(SIGSEGV); } -- cgit v0.10.2 From 2d6d79bbe589b74c0a6612fc88e4d150f8dfa1e1 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Fri, 20 Mar 2009 13:00:11 +0300 Subject: parisc: iosapic: fix build breakage drivers/parisc/iosapic.c:717: error: incompatible types in assignment irq_desc::affinity was changed from cpumask_t to cpumask_var_t in 7f7ace0cda (cpumask: update irq_desc to use cpumask_var_t) Signed-off-by: Alexander Beregalov Signed-off-by: Kyle McMartin diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 501aaf1..73348c4 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c @@ -714,7 +714,7 @@ static void iosapic_set_affinity_irq(unsigned int irq, if (dest_cpu < 0) return; - irq_desc[irq].affinity = cpumask_of_cpu(dest_cpu); + cpumask_copy(irq_desc[irq].affinity, cpumask_of(dest_cpu)); vi->txn_addr = txn_affinity_addr(irq, dest_cpu); spin_lock_irqsave(&iosapic_lock, flags); -- cgit v0.10.2 From 47e669ce10901dc92960096653d6b22990b5188f Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sun, 22 Mar 2009 03:58:40 +0000 Subject: parisc: fix macro expansion in atomic.h Signed-off-by: James Bottomley Signed-off-by: Kyle McMartin diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h index edbfe25..ada3e53 100644 --- a/arch/parisc/include/asm/atomic.h +++ b/arch/parisc/include/asm/atomic.h @@ -25,7 +25,7 @@ * Since "a" is usually an address, use one spinlock per cacheline. */ # define ATOMIC_HASH_SIZE 4 -# define ATOMIC_HASH(a) (&(__atomic_hash[ (((unsigned long) a)/L1_CACHE_BYTES) & (ATOMIC_HASH_SIZE-1) ])) +# define ATOMIC_HASH(a) (&(__atomic_hash[ (((unsigned long) (a))/L1_CACHE_BYTES) & (ATOMIC_HASH_SIZE-1) ])) extern raw_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned; @@ -222,13 +222,13 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) -#define atomic_add(i,v) ((void)(__atomic_add_return( ((int)i),(v)))) -#define atomic_sub(i,v) ((void)(__atomic_add_return(-((int)i),(v)))) +#define atomic_add(i,v) ((void)(__atomic_add_return( ((int)(i)),(v)))) +#define atomic_sub(i,v) ((void)(__atomic_add_return(-((int)(i)),(v)))) #define atomic_inc(v) ((void)(__atomic_add_return( 1,(v)))) #define atomic_dec(v) ((void)(__atomic_add_return( -1,(v)))) -#define atomic_add_return(i,v) (__atomic_add_return( ((int)i),(v))) -#define atomic_sub_return(i,v) (__atomic_add_return(-((int)i),(v))) +#define atomic_add_return(i,v) (__atomic_add_return( ((int)(i)),(v))) +#define atomic_sub_return(i,v) (__atomic_add_return(-((int)(i)),(v))) #define atomic_inc_return(v) (__atomic_add_return( 1,(v))) #define atomic_dec_return(v) (__atomic_add_return( -1,(v))) @@ -289,13 +289,13 @@ atomic64_read(const atomic64_t *v) return v->counter; } -#define atomic64_add(i,v) ((void)(__atomic64_add_return( ((s64)i),(v)))) -#define atomic64_sub(i,v) ((void)(__atomic64_add_return(-((s64)i),(v)))) +#define atomic64_add(i,v) ((void)(__atomic64_add_return( ((s64)(i)),(v)))) +#define atomic64_sub(i,v) ((void)(__atomic64_add_return(-((s64)(i)),(v)))) #define atomic64_inc(v) ((void)(__atomic64_add_return( 1,(v)))) #define atomic64_dec(v) ((void)(__atomic64_add_return( -1,(v)))) -#define atomic64_add_return(i,v) (__atomic64_add_return( ((s64)i),(v))) -#define atomic64_sub_return(i,v) (__atomic64_add_return(-((s64)i),(v))) +#define atomic64_add_return(i,v) (__atomic64_add_return( ((s64)(i)),(v))) +#define atomic64_sub_return(i,v) (__atomic64_add_return(-((s64)(i)),(v))) #define atomic64_inc_return(v) (__atomic64_add_return( 1,(v))) #define atomic64_dec_return(v) (__atomic64_add_return( -1,(v))) -- cgit v0.10.2 From 1ab2eaa2c16c2467bbd94514ec6c1fe5129546c7 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Fri, 20 Mar 2009 14:55:50 +0000 Subject: parisc: led: remove proc_dir_entry::owner proc_dir_entry::owner was removed in 0702c1c1a4 (proc 2/2: remove struct proc_dir_entry::owner) Signed-off-by: Alexander Beregalov Signed-off-by: Kyle McMartin diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c index 75ff6d7..9581d36 100644 --- a/drivers/parisc/led.c +++ b/drivers/parisc/led.c @@ -243,13 +243,11 @@ static int __init led_create_procfs(void) proc_pdc_root = proc_mkdir("pdc", 0); if (!proc_pdc_root) return -1; - proc_pdc_root->owner = THIS_MODULE; ent = create_proc_entry("led", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root); if (!ent) return -1; ent->data = (void *)LED_NOLCD; /* LED */ ent->read_proc = led_proc_read; ent->write_proc = led_proc_write; - ent->owner = THIS_MODULE; if (led_type == LED_HASLCD) { @@ -258,7 +256,6 @@ static int __init led_create_procfs(void) ent->data = (void *)LED_HASLCD; /* LCD */ ent->read_proc = led_proc_read; ent->write_proc = led_proc_write; - ent->owner = THIS_MODULE; } return 0; -- cgit v0.10.2 From d845e1fbf2d48f6556fbfae7ec04adf67ab14bca Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 1 Apr 2009 15:43:40 +0000 Subject: parisc: asm/pdc.h should include asm/page.h Fixes this build error: arch/parisc/kernel/pdc_cons.c:117: error: '__PAGE_OFFSET' undeclared Signed-off-by: Alexander Beregalov Signed-off-by: Kyle McMartin diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h index a26e98d..4ca510b 100644 --- a/arch/parisc/include/asm/pdc.h +++ b/arch/parisc/include/asm/pdc.h @@ -343,6 +343,8 @@ #ifdef __KERNEL__ +#include /* for __PAGE_OFFSET */ + extern int pdc_type; /* Values for pdc_type */ -- cgit v0.10.2 From f67d3c83f3f1e6523325628434bf19e5166b39b3 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Wed, 25 Mar 2009 14:09:10 +0000 Subject: parisc: select BUG always On Wed, Mar 25, 2009 at 05:02:21PM +0300, Alexander Beregalov wrote: > arch/parisc/kernel/traps.c:321: error: 'PARISC_BUG_BREAK_INSN' > undeclared (first use in this function) > > # CONFIG_BUG is not set > CONFIG_EMBEDDED=y > > Is it a reasonable config? imho, no. Signed-off-by: Kyle McMartin diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 7fd696f..3bbc744 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -15,6 +15,7 @@ config PARISC select RTC_CLASS select RTC_DRV_PARISC select INIT_ALL_POSSIBLE + select BUG help The PA-RISC microprocessor is designed by Hewlett-Packard and used in many of their workstations & servers (HP9000 700 and 800 series, -- cgit v0.10.2 From c18b4608958ff42ce9a1a55b0a6f40b714f47286 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Thu, 19 Mar 2009 10:54:07 +0000 Subject: parisc: drivers: fix warnings ccio-dma.c:456: warning: overflow in implicit constant conversion ccio-dma.c:459: warning: overflow in implicit constant conversion ccio-dma.c:1032: warning: unused variable 'j' ccio-dma.c:1031: warning: unused variable 'max' ccio-dma.c:1031: warning: unused variable 'min' ccio-dma.c:1031: warning: unused variable 'avg' ccio-dma.c:1403: warning: format '%08lx' expects type 'long unsigned int', but argument 3 has type 'resource_size_t' ccio-dma.c:1403: warning: format '%08lx' expects type 'long unsigned int', but argument 4 has type 'resource_size_t' ccio-dma.c:1554: warning: format '%lx' expects type 'long unsigned int', but argument 3 has type 'resource_size_t' dino.c:822: warning: format '%lx' expects type 'long unsigned int', but argument 4 has type 'resource_size_t' dino.c:822: warning: format '%lx' expects type 'long unsigned int', but argument 5 has type 'resource_size_t' dino.c:902: warning: format '%lx' expects type 'long unsigned int', but argument 3 has type 'resource_size_t' dino.c:902: warning: format '%lx' expects type 'long unsigned int', but argument 4 has type 'resource_size_t' asp.c:84: warning: format '%lx' expects type 'long unsigned int', but argument 4 has type 'resource_size_t' eisa.c:317: warning: format '%08lx' expects type 'long unsigned int', but argument 3 has type 'resource_size_t' eisa_enumerator.c:101: warning: format '%lx' expects type 'long unsigned int', but argument 2 has type 'resource_size_t' eisa_enumerator.c:101: warning: format '%lx' expects type 'long unsigned int', but argument 3 has type 'resource_size_t' eisa_enumerator.c:191: warning: format '%lx' expects type 'long unsigned int', but argument 2 has type 'resource_size_t' eisa_enumerator.c:191: warning: format '%lx' expects type 'long unsigned int', but argument 3 has type 'resource_size_t' Signed-off-by: Alexander Beregalov Signed-off-by: Kyle McMartin diff --git a/drivers/parisc/asp.c b/drivers/parisc/asp.c index 79311335..9ca2109 100644 --- a/drivers/parisc/asp.c +++ b/drivers/parisc/asp.c @@ -81,7 +81,7 @@ static int __init asp_init_chip(struct parisc_device *dev) asp.hpa = ASP_INTERRUPT_ADDR; printk(KERN_INFO "%s version %d at 0x%lx found.\n", - asp.name, asp.version, dev->hpa.start); + asp.name, asp.version, (unsigned long)dev->hpa.start); /* the IRQ ASP should use */ ret = -EBUSY; diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index cd4dd7e..5d610cb 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c @@ -406,8 +406,6 @@ resource_found: } ioc->avg_search[ioc->avg_idx++] = cr_start; ioc->avg_idx &= CCIO_SEARCH_SAMPLE - 1; -#endif -#ifdef CCIO_COLLECT_STATS ioc->used_pages += pages_needed; #endif /* @@ -453,10 +451,10 @@ ccio_free_range(struct ioc *ioc, dma_addr_t iova, unsigned long pages_mapped) unsigned long mask = ~(~0UL >> pages_mapped); CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 8); #else - CCIO_FREE_MAPPINGS(ioc, res_idx, 0xff, 8); + CCIO_FREE_MAPPINGS(ioc, res_idx, 0xffUL, 8); #endif } else if(pages_mapped <= 16) { - CCIO_FREE_MAPPINGS(ioc, res_idx, 0xffff, 16); + CCIO_FREE_MAPPINGS(ioc, res_idx, 0xffffUL, 16); } else if(pages_mapped <= 32) { CCIO_FREE_MAPPINGS(ioc, res_idx, ~(unsigned int)0, 32); #ifdef __LP64__ @@ -1028,8 +1026,10 @@ static int ccio_proc_info(struct seq_file *m, void *p) while (ioc != NULL) { unsigned int total_pages = ioc->res_size << 3; +#ifdef CCIO_COLLECT_STATS unsigned long avg = 0, min, max; int j; +#endif len += seq_printf(m, "%s\n", ioc->name); @@ -1060,8 +1060,7 @@ static int ccio_proc_info(struct seq_file *m, void *p) avg /= CCIO_SEARCH_SAMPLE; len += seq_printf(m, " Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n", min, avg, max); -#endif -#ifdef CCIO_COLLECT_STATS + len += seq_printf(m, "pci_map_single(): %8ld calls %8ld pages (avg %d/1000)\n", ioc->msingle_calls, ioc->msingle_pages, (int)((ioc->msingle_pages * 1000)/ioc->msingle_calls)); @@ -1400,7 +1399,7 @@ ccio_init_resource(struct resource *res, char *name, void __iomem *ioaddr) result = insert_resource(&iomem_resource, res); if (result < 0) { printk(KERN_ERR "%s() failed to claim CCIO bus address space (%08lx,%08lx)\n", - __func__, res->start, res->end); + __func__, (unsigned long)res->start, (unsigned long)res->end); } } @@ -1551,7 +1550,8 @@ static int __init ccio_probe(struct parisc_device *dev) ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn"; - printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name, dev->hpa.start); + printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name, + (unsigned long)dev->hpa.start); for (i = 0; i < ioc_count; i++) { ioc_p = &(*ioc_p)->next; diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index bb5a1c9..52ae0b1 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c @@ -819,7 +819,9 @@ dino_bridge_init(struct dino_device *dino_dev, const char *name) result = ccio_request_resource(dino_dev->hba.dev, &res[i]); if (result < 0) { - printk(KERN_ERR "%s: failed to claim PCI Bus address space %d (0x%lx-0x%lx)!\n", name, i, res[i].start, res[i].end); + printk(KERN_ERR "%s: failed to claim PCI Bus address " + "space %d (0x%lx-0x%lx)!\n", name, i, + (unsigned long)res[i].start, (unsigned long)res[i].end); return result; } } @@ -899,7 +901,8 @@ static int __init dino_common_init(struct parisc_device *dev, if (request_resource(&ioport_resource, res) < 0) { printk(KERN_ERR "%s: request I/O Port region failed " "0x%lx/%lx (hpa 0x%p)\n", - name, res->start, res->end, dino_dev->hba.base_addr); + name, (unsigned long)res->start, (unsigned long)res->end, + dino_dev->hba.base_addr); return 1; } diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c index 7891db5..f415fdd 100644 --- a/drivers/parisc/eisa.c +++ b/drivers/parisc/eisa.c @@ -314,7 +314,7 @@ static int __init eisa_probe(struct parisc_device *dev) char *name = is_mongoose(dev) ? "Mongoose" : "Wax"; printk(KERN_INFO "%s EISA Adapter found at 0x%08lx\n", - name, dev->hpa.start); + name, (unsigned long)dev->hpa.start); eisa_dev.hba.dev = dev; eisa_dev.hba.iommu = ccio_get_iommu(dev); diff --git a/drivers/parisc/eisa_enumerator.c b/drivers/parisc/eisa_enumerator.c index 6d8aae0..c709ecc 100644 --- a/drivers/parisc/eisa_enumerator.c +++ b/drivers/parisc/eisa_enumerator.c @@ -98,7 +98,7 @@ static int configure_memory(const unsigned char *buf, res->start = mem_parent->start + get_24(buf+len+2); res->end = res->start + get_16(buf+len+5)*1024; res->flags = IORESOURCE_MEM; - printk("memory %lx-%lx ", res->start, res->end); + printk("memory %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end); result = request_resource(mem_parent, res); if (result < 0) { printk("\n" KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n"); @@ -188,7 +188,7 @@ static int configure_port(const unsigned char *buf, struct resource *io_parent, res->start = get_16(buf+len+1); res->end = get_16(buf+len+1)+(c&HPEE_PORT_SIZE_MASK)+1; res->flags = IORESOURCE_IO; - printk("ioports %lx-%lx ", res->start, res->end); + printk("ioports %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end); result = request_resource(io_parent, res); if (result < 0) { printk("\n" KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n"); -- cgit v0.10.2 From 91400ac365da35b18036b46bdda27ddbcee4a663 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Wed, 18 Feb 2009 22:12:21 +0000 Subject: parisc: fix "make tar-pkg" Signed-off-by: Helge Deller Signed-off-by: Kyle McMartin diff --git a/scripts/package/buildtar b/scripts/package/buildtar index 28574ae..b1fd48d 100644 --- a/scripts/package/buildtar +++ b/scripts/package/buildtar @@ -75,6 +75,10 @@ case "${ARCH}" in alpha) [ -f "${objtree}/arch/alpha/boot/vmlinux.gz" ] && cp -v -- "${objtree}/arch/alpha/boot/vmlinux.gz" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}" ;; + parisc*) + [ -f "${KBUILD_IMAGE}" ] && cp -v -- "${KBUILD_IMAGE}" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}" + [ -f "${objtree}/lifimage" ] && cp -v -- "${objtree}/lifimage" "${tmpdir}/boot/lifimage-${KERNELRELEASE}" + ;; vax) [ -f "${objtree}/vmlinux.SYS" ] && cp -v -- "${objtree}/vmlinux.SYS" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}.SYS" [ -f "${objtree}/vmlinux.dsk" ] && cp -v -- "${objtree}/vmlinux.dsk" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}.dsk" -- cgit v0.10.2 From bb7350194130ae6bd3fdec16fe1b7597c1c0bb8d Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Thu, 2 Apr 2009 02:40:41 +0000 Subject: parisc: fix build when ARCH_HAS_KMAP When we build for PA8X00, we define ARCH_HAS_KMAP, which results in the kmap_types.h include in highmem.h getting skipped... In file included from include/linux/pagemap.h:10, from include/linux/mempolicy.h:62, from init/main.c:52: include/linux/highmem.h:196: warning: 'enum km_type' declared inside parameter list include/linux/highmem.h:196: warning: its scope is only this definition or declaration, which is probably not what you want include/linux/highmem.h:196: error: parameter 1 ('type') has incomplete type Signed-off-by: Kyle McMartin diff --git a/arch/parisc/include/asm/cacheflush.h b/arch/parisc/include/asm/cacheflush.h index b7ca6dc..7243951 100644 --- a/arch/parisc/include/asm/cacheflush.h +++ b/arch/parisc/include/asm/cacheflush.h @@ -97,6 +97,9 @@ void mark_rodata_ro(void); #ifdef CONFIG_PA8X00 /* Only pa8800, pa8900 needs this */ + +#include + #define ARCH_HAS_KMAP void kunmap_parisc(void *addr); -- cgit v0.10.2 From bf589a349b9a41ea202ddb8115b18f543b944bfd Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Sun, 15 Mar 2009 16:44:25 -0400 Subject: parisc: Move kernel Elf_Fdesc define to elf.h probably won't be exported to userspace, but play it safe and cram it in a #ifdef __KERNEL__ guard. Signed-off-by: Kyle McMartin diff --git a/arch/parisc/include/asm/elf.h b/arch/parisc/include/asm/elf.h index 7fa6757..9c802eb 100644 --- a/arch/parisc/include/asm/elf.h +++ b/arch/parisc/include/asm/elf.h @@ -168,6 +168,16 @@ typedef struct elf64_fdesc { __u64 gp; } Elf64_Fdesc; +#ifdef __KERNEL__ + +#ifdef CONFIG_64BIT +#define Elf_Fdesc Elf64_Fdesc +#else +#define Elf_Fdesc Elf32_Fdesc +#endif /*CONFIG_64BIT*/ + +#endif /*__KERNEL__*/ + /* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */ #define PT_HP_TLS (PT_LOOS + 0x0) diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index 9013243..3439cbd 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -115,8 +115,6 @@ struct got_entry { Elf32_Addr addr; }; -#define Elf_Fdesc Elf32_Fdesc - struct stub_entry { Elf32_Word insns[2]; /* each stub entry has two insns */ }; @@ -125,8 +123,6 @@ struct got_entry { Elf64_Addr addr; }; -#define Elf_Fdesc Elf64_Fdesc - struct stub_entry { Elf64_Word insns[4]; /* each stub entry has four insns */ }; -- cgit v0.10.2 From b609308e1415efebdf79ebd553f4dd47b0ff2722 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Sun, 15 Mar 2009 16:49:55 -0400 Subject: parisc: move dereference_function_descriptor to process.c Commit deac93df26b20cf8438339b5935b5f5643bc30c9 fixed up printing of %pF on parisc, but added the dereference_function_descriptor prototype to module.c... this isn't a particularly wise idea as module.c might not always be compiled. Signed-off-by: Kyle McMartin diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index 3439cbd..ecd1c50 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -61,9 +61,7 @@ #include #include #include -#include -#include #include #if 0 @@ -912,15 +910,3 @@ void module_arch_cleanup(struct module *mod) deregister_unwind_table(mod); module_bug_cleanup(mod); } - -#ifdef CONFIG_64BIT -void *dereference_function_descriptor(void *ptr) -{ - Elf64_Fdesc *desc = ptr; - void *p; - - if (!probe_kernel_address(&desc->addr, p)) - ptr = p; - return ptr; -} -#endif diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index ad585fd..029831df 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -46,14 +46,15 @@ #include #include #include +#include #include #include #include #include #include -#include #include +#include /* * The idle thread. There's no useful work to be @@ -390,3 +391,15 @@ get_wchan(struct task_struct *p) } while (count++ < 16); return 0; } + +#ifdef CONFIG_64BIT +void *dereference_function_descriptor(void *ptr) +{ + Elf64_Fdesc *desc = ptr; + void *p; + + if (!probe_kernel_address(&desc->addr, p)) + ptr = p; + return ptr; +} +#endif -- cgit v0.10.2