diff options
Diffstat (limited to 'arch/parisc/kernel')
-rw-r--r-- | arch/parisc/kernel/Makefile | 4 | ||||
-rw-r--r-- | arch/parisc/kernel/audit.c | 81 | ||||
-rw-r--r-- | arch/parisc/kernel/compat_audit.c | 40 | ||||
-rw-r--r-- | arch/parisc/kernel/hardware.c | 7 | ||||
-rw-r--r-- | arch/parisc/kernel/head.S | 10 | ||||
-rw-r--r-- | arch/parisc/kernel/irq.c | 21 | ||||
-rw-r--r-- | arch/parisc/kernel/module.c | 2 | ||||
-rw-r--r-- | arch/parisc/kernel/ptrace.c | 26 | ||||
-rw-r--r-- | arch/parisc/kernel/setup.c | 8 | ||||
-rw-r--r-- | arch/parisc/kernel/signal32.c | 2 | ||||
-rw-r--r-- | arch/parisc/kernel/signal32.h | 2 | ||||
-rw-r--r-- | arch/parisc/kernel/smp.c | 13 | ||||
-rw-r--r-- | arch/parisc/kernel/sys_parisc.c | 25 | ||||
-rw-r--r-- | arch/parisc/kernel/syscall.S | 6 | ||||
-rw-r--r-- | arch/parisc/kernel/traps.c | 11 | ||||
-rw-r--r-- | arch/parisc/kernel/unwind.c | 9 | ||||
-rw-r--r-- | arch/parisc/kernel/vmlinux.lds.S | 138 |
17 files changed, 254 insertions, 151 deletions
diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile index 66ee3f12df5..ff87b4603e3 100644 --- a/arch/parisc/kernel/Makefile +++ b/arch/parisc/kernel/Makefile @@ -29,7 +29,9 @@ 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 +obj-$(CONFIG_AUDIT) += audit.o +obj64-$(CONFIG_AUDIT) += compat_audit.o # only supported for PCX-W/U in 64-bit mode at the moment -obj-$(CONFIG_64BIT) += perf.o perf_asm.o +obj-$(CONFIG_64BIT) += perf.o perf_asm.o $(obj64-y) obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o diff --git a/arch/parisc/kernel/audit.c b/arch/parisc/kernel/audit.c new file mode 100644 index 00000000000..eb64a6148c8 --- /dev/null +++ b/arch/parisc/kernel/audit.c @@ -0,0 +1,81 @@ +#include <linux/init.h> +#include <linux/types.h> +#include <linux/audit.h> +#include <asm/unistd.h> + +static unsigned dir_class[] = { +#include <asm-generic/audit_dir_write.h> +~0U +}; + +static unsigned read_class[] = { +#include <asm-generic/audit_read.h> +~0U +}; + +static unsigned write_class[] = { +#include <asm-generic/audit_write.h> +~0U +}; + +static unsigned chattr_class[] = { +#include <asm-generic/audit_change_attr.h> +~0U +}; + +static unsigned signal_class[] = { +#include <asm-generic/audit_signal.h> +~0U +}; + +int audit_classify_arch(int arch) +{ +#ifdef CONFIG_COMPAT + if (arch == AUDIT_ARCH_PARISC) + return 1; +#endif + return 0; +} + +int audit_classify_syscall(int abi, unsigned syscall) +{ +#ifdef CONFIG_COMPAT + extern int parisc32_classify_syscall(unsigned); + if (abi == AUDIT_ARCH_PARISC) + return parisc32_classify_syscall(syscall); +#endif + switch (syscall) { + case __NR_open: + return 2; + case __NR_openat: + return 3; + case __NR_execve: + return 5; + default: + return 0; + } +} + +static int __init audit_classes_init(void) +{ +#ifdef CONFIG_COMPAT + extern __u32 parisc32_dir_class[]; + extern __u32 parisc32_write_class[]; + extern __u32 parisc32_read_class[]; + extern __u32 parisc32_chattr_class[]; + extern __u32 parisc32_signal_class[]; + audit_register_class(AUDIT_CLASS_WRITE_32, parisc32_write_class); + audit_register_class(AUDIT_CLASS_READ_32, parisc32_read_class); + audit_register_class(AUDIT_CLASS_DIR_WRITE_32, parisc32_dir_class); + audit_register_class(AUDIT_CLASS_CHATTR_32, parisc32_chattr_class); + audit_register_class(AUDIT_CLASS_SIGNAL_32, parisc32_signal_class); +#endif + audit_register_class(AUDIT_CLASS_WRITE, write_class); + audit_register_class(AUDIT_CLASS_READ, read_class); + audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class); + audit_register_class(AUDIT_CLASS_CHATTR, chattr_class); + audit_register_class(AUDIT_CLASS_SIGNAL, signal_class); + return 0; +} + +__initcall(audit_classes_init); diff --git a/arch/parisc/kernel/compat_audit.c b/arch/parisc/kernel/compat_audit.c new file mode 100644 index 00000000000..c74478f6bc7 --- /dev/null +++ b/arch/parisc/kernel/compat_audit.c @@ -0,0 +1,40 @@ +#include <asm/unistd.h> + +unsigned int parisc32_dir_class[] = { +#include <asm-generic/audit_dir_write.h> +~0U +}; + +unsigned int parisc32_chattr_class[] = { +#include <asm-generic/audit_change_attr.h> +~0U +}; + +unsigned int parisc32_write_class[] = { +#include <asm-generic/audit_write.h> +~0U +}; + +unsigned int parisc32_read_class[] = { +#include <asm-generic/audit_read.h> +~0U +}; + +unsigned int parisc32_signal_class[] = { +#include <asm-generic/audit_signal.h> +~0U +}; + +int parisc32_classify_syscall(unsigned syscall) +{ + switch (syscall) { + case __NR_open: + return 2; + case __NR_openat: + return 3; + case __NR_execve: + return 5; + default: + return 1; + } +} diff --git a/arch/parisc/kernel/hardware.c b/arch/parisc/kernel/hardware.c index 06cb3992907..608716f8496 100644 --- a/arch/parisc/kernel/hardware.c +++ b/arch/parisc/kernel/hardware.c @@ -36,6 +36,9 @@ * HP PARISC Hardware Database * Access to this database is only possible during bootup * so don't reference this table after starting the init process + * + * NOTE: Product names which are listed here and ends with a '?' + * are guessed. If you know the correct name, please let us know. */ static struct hp_hardware hp_hardware_list[] = { @@ -222,7 +225,7 @@ static struct hp_hardware hp_hardware_list[] = { {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,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"}, @@ -276,9 +279,11 @@ static struct hp_hardware hp_hardware_list[] = { {HPHW_NPROC,0x888,0x4,0x91,"Storm Peak Fast DC-"}, {HPHW_NPROC,0x889,0x4,0x91,"Storm Peak Fast"}, {HPHW_NPROC,0x88A,0x4,0x91,"Crestone Peak Slow"}, + {HPHW_NPROC,0x88B,0x4,0x91,"Crestone Peak Fast?"}, {HPHW_NPROC,0x88C,0x4,0x91,"Orca Mako+"}, {HPHW_NPROC,0x88D,0x4,0x91,"Rainier/Medel Mako+ Slow"}, {HPHW_NPROC,0x88E,0x4,0x91,"Rainier/Medel Mako+ Fast"}, + {HPHW_NPROC,0x892,0x4,0x91,"Mt. Hamilton Slow Mako+?"}, {HPHW_NPROC,0x894,0x4,0x91,"Mt. Hamilton Fast Mako+"}, {HPHW_NPROC,0x895,0x4,0x91,"Storm Peak Slow Mako+"}, {HPHW_NPROC,0x896,0x4,0x91,"Storm Peak Fast Mako+"}, diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S index 37aabd772fb..d4dc588c0dc 100644 --- a/arch/parisc/kernel/head.S +++ b/arch/parisc/kernel/head.S @@ -41,9 +41,7 @@ END(boot_args) .import fault_vector_11,code /* IVA parisc 1.1 32 bit */ .import $global$ /* forward declaration */ #endif /*!CONFIG_64BIT*/ - .export _stext,data /* Kernel want it this way! */ -_stext: -ENTRY(stext) +ENTRY(parisc_kernel_start) .proc .callinfo @@ -195,6 +193,8 @@ common_stext: ldw MEM_PDC_HI(%r0),%r6 depd %r6, 31, 32, %r3 /* move to upper word */ + mfctl %cr30,%r6 /* PCX-W2 firmware bug */ + ldo PDC_PSW(%r0),%arg0 /* 21 */ ldo PDC_PSW_SET_DEFAULTS(%r0),%arg1 /* 2 */ ldo PDC_PSW_WIDE_BIT(%r0),%arg2 /* 2 */ @@ -203,6 +203,8 @@ common_stext: copy %r0,%arg3 stext_pdc_ret: + mtctl %r6,%cr30 /* restore task thread info */ + /* restore rfi target address*/ ldd TI_TASK-THREAD_SZ_ALGN(%sp), %r10 tophys_r1 %r10 @@ -343,7 +345,7 @@ smp_slave_stext: .procend #endif /* CONFIG_SMP */ -ENDPROC(stext) +ENDPROC(parisc_kernel_start) #ifndef CONFIG_64BIT .section .data..read_mostly diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index 2e6443b1e92..8ceac478560 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -179,10 +179,6 @@ int arch_show_interrupts(struct seq_file *p, int prec) for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->irq_resched_count); 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_puts(p, " Function call interrupts\n"); #endif seq_printf(p, "%*s: ", prec, "UAH"); for_each_online_cpu(j) @@ -499,22 +495,9 @@ static void execute_on_irq_stack(void *func, unsigned long param1) *irq_stack_in_use = 1; } -asmlinkage void do_softirq(void) +void do_softirq_own_stack(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); + execute_on_irq_stack(__do_softirq, 0); } #endif /* CONFIG_IRQSTACKS */ diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index 2a625fb063e..50dfafc3f2c 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -219,7 +219,7 @@ void *module_alloc(unsigned long size) * init_data correctly */ return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END, GFP_KERNEL | __GFP_HIGHMEM, - PAGE_KERNEL_RWX, -1, + PAGE_KERNEL_RWX, NUMA_NO_NODE, __builtin_return_address(0)); } diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c index 534abd4936e..e842ee233db 100644 --- a/arch/parisc/kernel/ptrace.c +++ b/arch/parisc/kernel/ptrace.c @@ -19,6 +19,7 @@ #include <linux/security.h> #include <linux/compat.h> #include <linux/signal.h> +#include <linux/audit.h> #include <asm/uaccess.h> #include <asm/pgtable.h> @@ -267,11 +268,28 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, long do_syscall_trace_enter(struct pt_regs *regs) { + long ret = 0; + if (test_thread_flag(TIF_SYSCALL_TRACE) && tracehook_report_syscall_entry(regs)) - return -1L; - - return regs->gr[20]; + ret = -1L; + +#ifdef CONFIG_64BIT + if (!is_compat_task()) + audit_syscall_entry(AUDIT_ARCH_PARISC64, + regs->gr[20], + regs->gr[26], regs->gr[25], + regs->gr[24], regs->gr[23]); + else +#endif + audit_syscall_entry(AUDIT_ARCH_PARISC, + regs->gr[20] & 0xffffffff, + regs->gr[26] & 0xffffffff, + regs->gr[25] & 0xffffffff, + regs->gr[24] & 0xffffffff, + regs->gr[23] & 0xffffffff); + + return ret ? : regs->gr[20]; } void do_syscall_trace_exit(struct pt_regs *regs) @@ -279,6 +297,8 @@ void do_syscall_trace_exit(struct pt_regs *regs) int stepping = test_thread_flag(TIF_SINGLESTEP) || test_thread_flag(TIF_BLOCKSTEP); + audit_syscall_exit(regs); + if (stepping || test_thread_flag(TIF_SYSCALL_TRACE)) tracehook_report_syscall_exit(regs, stepping); } diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c index 7349a3fedfc..72a3c658ad7 100644 --- a/arch/parisc/kernel/setup.c +++ b/arch/parisc/kernel/setup.c @@ -318,8 +318,12 @@ static int __init parisc_init(void) pdc_stable_write(0x40, &osid, sizeof(osid)); processor_init(); - printk(KERN_INFO "CPU(s): %d x %s at %d.%06d MHz\n", - num_present_cpus(), +#ifdef CONFIG_SMP + pr_info("CPU(s): %d out of %d %s at %d.%06d MHz online\n", + num_online_cpus(), num_present_cpus(), +#else + pr_info("CPU(s): 1 x %s at %d.%06d MHz\n", +#endif boot_cpu_data.cpu_name, boot_cpu_data.cpu_hz / 1000000, boot_cpu_data.cpu_hz % 1000000 ); diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c index 6c6a271a614..984abbee71c 100644 --- a/arch/parisc/kernel/signal32.c +++ b/arch/parisc/kernel/signal32.c @@ -319,7 +319,7 @@ copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from) } int -copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from) +copy_siginfo_to_user32 (compat_siginfo_t __user *to, const siginfo_t *from) { compat_uptr_t addr; compat_int_t val; diff --git a/arch/parisc/kernel/signal32.h b/arch/parisc/kernel/signal32.h index 72ab41a51f3..af51d4ccee4 100644 --- a/arch/parisc/kernel/signal32.h +++ b/arch/parisc/kernel/signal32.h @@ -34,7 +34,7 @@ struct compat_ucontext { /* ELF32 signal handling */ -int copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from); +int copy_siginfo_to_user32 (compat_siginfo_t __user *to, const siginfo_t *from); int copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from); /* In a deft move of uber-hackery, we decide to carry the top half of all diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 8a252f2d6c0..ceda229ea6c 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -72,7 +72,6 @@ enum ipi_message_type { IPI_NOP=0, IPI_RESCHEDULE=1, IPI_CALL_FUNC, - IPI_CALL_FUNC_SINGLE, IPI_CPU_START, IPI_CPU_STOP, IPI_CPU_TEST @@ -126,11 +125,6 @@ ipi_interrupt(int irq, void *dev_id) unsigned long ops; unsigned long flags; - /* Count this now; we may make a call that never returns. */ - inc_irq_stat(irq_call_count); - - mb(); /* Order interrupt and bit testing. */ - for (;;) { spinlock_t *lock = &per_cpu(ipi_lock, this_cpu); spin_lock_irqsave(lock, flags); @@ -164,11 +158,6 @@ ipi_interrupt(int irq, void *dev_id) generic_smp_call_function_interrupt(); break; - case IPI_CALL_FUNC_SINGLE: - smp_debug(100, KERN_DEBUG "CPU%d IPI_CALL_FUNC_SINGLE\n", this_cpu); - generic_smp_call_function_single_interrupt(); - break; - case IPI_CPU_START: smp_debug(100, KERN_DEBUG "CPU%d IPI_CPU_START\n", this_cpu); break; @@ -260,7 +249,7 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask) void arch_send_call_function_single_ipi(int cpu) { - send_IPI_single(cpu, IPI_CALL_FUNC_SINGLE); + send_IPI_single(cpu, IPI_CALL_FUNC); } /* diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 5dfd248e3f1..0d3a9d4927b 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -61,8 +61,15 @@ static int get_offset(struct address_space *mapping) return (unsigned long) mapping >> 8; } -static unsigned long get_shared_area(struct address_space *mapping, - unsigned long addr, unsigned long len, unsigned long pgoff) +static unsigned long shared_align_offset(struct file *filp, unsigned long pgoff) +{ + struct address_space *mapping = filp ? filp->f_mapping : NULL; + + return (get_offset(mapping) + pgoff) << PAGE_SHIFT; +} + +static unsigned long get_shared_area(struct file *filp, unsigned long addr, + unsigned long len, unsigned long pgoff) { struct vm_unmapped_area_info info; @@ -71,7 +78,7 @@ static unsigned long get_shared_area(struct address_space *mapping, info.low_limit = PAGE_ALIGN(addr); info.high_limit = TASK_SIZE; info.align_mask = PAGE_MASK & (SHMLBA - 1); - info.align_offset = (get_offset(mapping) + pgoff) << PAGE_SHIFT; + info.align_offset = shared_align_offset(filp, pgoff); return vm_unmapped_area(&info); } @@ -82,20 +89,18 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, return -ENOMEM; if (flags & MAP_FIXED) { if ((flags & MAP_SHARED) && - (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)) + (addr - shared_align_offset(filp, pgoff)) & (SHMLBA - 1)) return -EINVAL; return addr; } if (!addr) addr = TASK_UNMAPPED_BASE; - if (filp) { - addr = get_shared_area(filp->f_mapping, addr, len, pgoff); - } else if(flags & MAP_SHARED) { - addr = get_shared_area(NULL, addr, len, pgoff); - } else { + if (filp || (flags & MAP_SHARED)) + addr = get_shared_area(filp, addr, len, pgoff); + else addr = get_unshared_area(addr, len); - } + return addr; } diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index e767ab733e3..a63bb179f79 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -649,10 +649,8 @@ cas_action: /* Two exception table entries, one for the load, the other for the store. Either return -EFAULT. Each of the entries must be relocated. */ - .section __ex_table,"aw" - ASM_ULONG_INSN (1b - linux_gateway_page), (3b - linux_gateway_page) - ASM_ULONG_INSN (2b - linux_gateway_page), (3b - linux_gateway_page) - .previous + ASM_EXCEPTIONTABLE_ENTRY(1b-linux_gateway_page, 3b-linux_gateway_page) + ASM_EXCEPTIONTABLE_ENTRY(2b-linux_gateway_page, 3b-linux_gateway_page) /* Make sure nothing else is placed on this page */ diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index 04e47c6a456..1cd1d0c83b6 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -291,11 +291,6 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err) do_exit(SIGSEGV); } -int syscall_ipi(int (*syscall) (struct pt_regs *), struct pt_regs *regs) -{ - return syscall(regs); -} - /* gdb uses break 4,8 */ #define GDB_BREAK_INSN 0x10004 static void handle_gdb_break(struct pt_regs *regs, int wot) @@ -805,14 +800,14 @@ void notrace handle_interruption(int code, struct pt_regs *regs) else { /* - * The kernel should never fault on its own address space. + * The kernel should never fault on its own address space, + * unless pagefault_disable() was called before. */ - if (fault_space == 0) + if (fault_space == 0 && !in_atomic()) { pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC); parisc_terminate("Kernel Fault", regs, code, fault_address); - } } diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c index 76ed62ed785..ddd988b267a 100644 --- a/arch/parisc/kernel/unwind.c +++ b/arch/parisc/kernel/unwind.c @@ -168,7 +168,7 @@ void unwind_table_remove(struct unwind_table *table) } /* Called from setup_arch to import the kernel unwind info */ -int unwind_init(void) +int __init unwind_init(void) { long start, stop; register unsigned long gp __asm__ ("r27"); @@ -233,7 +233,6 @@ static void unwind_frame_regs(struct unwind_frame_info *info) e = find_unwind_entry(info->ip); if (e == NULL) { unsigned long sp; - extern char _stext[], _etext[]; dbg("Cannot find unwind entry for 0x%lx; forced unwinding\n", info->ip); @@ -281,8 +280,7 @@ static void unwind_frame_regs(struct unwind_frame_info *info) break; info->prev_ip = tmp; sp = info->prev_sp; - } while (info->prev_ip < (unsigned long)_stext || - info->prev_ip > (unsigned long)_etext); + } while (!kernel_text_address(info->prev_ip)); info->rp = 0; @@ -435,9 +433,8 @@ unsigned long return_address(unsigned int level) do { if (unwind_once(&info) < 0 || info.ip == 0) return 0; - if (!__kernel_text_address(info.ip)) { + if (!kernel_text_address(info.ip)) return 0; - } } while (info.ip && level--); return info.ip; diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S index 4bb095a2f6f..0dacc5ca555 100644 --- a/arch/parisc/kernel/vmlinux.lds.S +++ b/arch/parisc/kernel/vmlinux.lds.S @@ -6,24 +6,19 @@ * Copyright (C) 2000 Michael Ang <mang with subcarrier.org> * Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org> * Copyright (C) 2003 James Bottomley <jejb with parisc-linux.org> - * Copyright (C) 2006 Helge Deller <deller@gmx.de> - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Copyright (C) 2006-2013 Helge Deller <deller@gmx.de> + */ + +/* + * Put page table entries (swapper_pg_dir) as the first thing in .bss. This + * will ensure that it has .bss alignment (PAGE_SIZE). */ +#define BSS_FIRST_SECTIONS *(.data..vm0.pmd) \ + *(.data..vm0.pgd) \ + *(.data..vm0.pte) + #include <asm-generic/vmlinux.lds.h> + /* needed for the processor specific cache alignment size */ #include <asm/cache.h> #include <asm/page.h> @@ -39,7 +34,7 @@ OUTPUT_FORMAT("elf64-hppa-linux") OUTPUT_ARCH(hppa:hppa2.0w) #endif -ENTRY(_stext) +ENTRY(parisc_kernel_start) #ifndef CONFIG_64BIT jiffies = jiffies_64 + 4; #else @@ -49,11 +44,29 @@ SECTIONS { . = KERNEL_BINARY_TEXT_START; + __init_begin = .; + HEAD_TEXT_SECTION + INIT_TEXT_SECTION(8) + + . = ALIGN(PAGE_SIZE); + INIT_DATA_SECTION(PAGE_SIZE) + /* we have to discard exit text and such at runtime, not link time */ + .exit.text : + { + EXIT_TEXT + } + .exit.data : + { + EXIT_DATA + } + PERCPU_SECTION(8) + . = ALIGN(PAGE_SIZE); + __init_end = .; + /* freed after init ends here */ + _text = .; /* Text and read-only data */ - .head ALIGN(16) : { - HEAD_TEXT - } = 0 - .text ALIGN(16) : { + _stext = .; + .text ALIGN(PAGE_SIZE) : { TEXT_TEXT SCHED_TEXT LOCK_TEXT @@ -68,21 +81,28 @@ SECTIONS *(.lock.text) /* out-of-line lock text */ *(.gnu.warning) } - /* End of text section */ + . = ALIGN(PAGE_SIZE); _etext = .; + /* End of text section */ /* Start of data section */ _sdata = .; - RODATA + RO_DATA_SECTION(8) - /* writeable */ - /* Make sure this is page aligned so - * that we can properly leave these - * as writable - */ - . = ALIGN(PAGE_SIZE); - data_start = .; +#ifdef CONFIG_64BIT + . = ALIGN(16); + /* Linkage tables */ + .opd : { + *(.opd) + } PROVIDE (__gp = .); + .plt : { + *(.plt) + } + .dlt : { + *(.dlt) + } +#endif /* unwind info */ .PARISC.unwind : { @@ -91,7 +111,15 @@ SECTIONS __stop___unwind = .; } - EXCEPTION_TABLE(16) + /* writeable */ + /* Make sure this is page aligned so + * that we can properly leave these + * as writable + */ + . = ALIGN(PAGE_SIZE); + data_start = .; + + EXCEPTION_TABLE(8) NOTES /* Data */ @@ -107,54 +135,8 @@ SECTIONS _edata = .; /* BSS */ - __bss_start = .; - /* page table entries need to be PAGE_SIZE aligned */ - . = ALIGN(PAGE_SIZE); - .data..vmpages : { - *(.data..vm0.pmd) - *(.data..vm0.pgd) - *(.data..vm0.pte) - } - .bss : { - *(.bss) - *(COMMON) - } - __bss_stop = .; - -#ifdef CONFIG_64BIT - . = ALIGN(16); - /* Linkage tables */ - .opd : { - *(.opd) - } PROVIDE (__gp = .); - .plt : { - *(.plt) - } - .dlt : { - *(.dlt) - } -#endif + BSS_SECTION(PAGE_SIZE, PAGE_SIZE, 8) - /* reserve space for interrupt stack by aligning __init* to 16k */ - . = ALIGN(16384); - __init_begin = .; - INIT_TEXT_SECTION(16384) - . = ALIGN(PAGE_SIZE); - INIT_DATA_SECTION(16) - /* we have to discard exit text and such at runtime, not link time */ - .exit.text : - { - EXIT_TEXT - } - .exit.data : - { - EXIT_DATA - } - - PERCPU_SECTION(L1_CACHE_BYTES) - . = ALIGN(PAGE_SIZE); - __init_end = .; - /* freed after init ends here */ _end = . ; STABS_DEBUG |