diff options
Diffstat (limited to 'arch/mips/kernel')
29 files changed, 240 insertions, 332 deletions
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index 8d006ec65677..2c1e1d02338b 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c @@ -183,9 +183,6 @@ void output_mm_defines(void) OFFSET(MM_PGD, mm_struct, pgd); OFFSET(MM_CONTEXT, mm_struct, context); BLANK(); - DEFINE(_PAGE_SIZE, PAGE_SIZE); - DEFINE(_PAGE_SHIFT, PAGE_SHIFT); - BLANK(); DEFINE(_PGD_T_SIZE, sizeof(pgd_t)); DEFINE(_PMD_T_SIZE, sizeof(pmd_t)); DEFINE(_PTE_T_SIZE, sizeof(pte_t)); diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c index 02b7713cf71c..408d0a07b3a3 100644 --- a/arch/mips/kernel/cpu-bugs64.c +++ b/arch/mips/kernel/cpu-bugs64.c @@ -167,7 +167,7 @@ static inline void check_mult_sh(void) panic(bug64hit, !R4000_WAR ? r4kwar : nowar); } -static volatile int daddi_ov __cpuinitdata = 0; +static volatile int daddi_ov __cpuinitdata; asmlinkage void __init do_daddi_ov(struct pt_regs *regs) { diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 1abe9905c9c1..f709657e4dcd 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -31,7 +31,7 @@ * The wait instruction stops the pipeline and reduces the power consumption of * the CPU very much. */ -void (*cpu_wait)(void) = NULL; +void (*cpu_wait)(void); static void r3081_wait(void) { @@ -91,16 +91,13 @@ static void rm7k_wait_irqoff(void) local_irq_enable(); } -/* The Au1xxx wait is available only if using 32khz counter or - * external timer source, but specifically not CP0 Counter. */ -int allow_au1k_wait; - +/* + * The Au1xxx wait is available only if using 32khz counter or + * external timer source, but specifically not CP0 Counter. + * alchemy/common/time.c may override cpu_wait! + */ static void au1k_wait(void) { - if (!allow_au1k_wait) - return; - - /* using the wait instruction makes CP0 counter unusable */ __asm__(" .set mips3 \n" " cache 0x14, 0(%0) \n" " cache 0x14, 32(%0) \n" @@ -115,7 +112,7 @@ static void au1k_wait(void) : : "r" (au1k_wait)); } -static int __initdata nowait = 0; +static int __initdata nowait; static int __init wait_disable(char *s) { @@ -159,6 +156,9 @@ void __init check_wait(void) case CPU_25KF: case CPU_PR4450: case CPU_BCM3302: + case CPU_BCM6338: + case CPU_BCM6348: + case CPU_BCM6358: case CPU_CAVIUM_OCTEON: cpu_wait = r4k_wait; break; @@ -857,6 +857,7 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu) decode_configs(c); switch (c->processor_id & 0xff00) { case PRID_IMP_BCM3302: + /* same as PRID_IMP_BCM6338 */ c->cputype = CPU_BCM3302; __cpu_name[cpu] = "Broadcom BCM3302"; break; @@ -864,6 +865,25 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu) c->cputype = CPU_BCM4710; __cpu_name[cpu] = "Broadcom BCM4710"; break; + case PRID_IMP_BCM6345: + c->cputype = CPU_BCM6345; + __cpu_name[cpu] = "Broadcom BCM6345"; + break; + case PRID_IMP_BCM6348: + c->cputype = CPU_BCM6348; + __cpu_name[cpu] = "Broadcom BCM6348"; + break; + case PRID_IMP_BCM4350: + switch (c->processor_id & 0xf0) { + case PRID_REV_BCM6358: + c->cputype = CPU_BCM6358; + __cpu_name[cpu] = "Broadcom BCM6358"; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } + break; } } diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index 492a0a8d70fb..531ce7b16124 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S @@ -188,7 +188,8 @@ NESTED(kernel_entry, 16, sp) # kernel entry point MTC0 zero, CP0_CONTEXT # clear context register PTR_LA $28, init_thread_union - PTR_LI sp, _THREAD_SIZE - 32 + /* Set the SP after an empty pt_regs. */ + PTR_LI sp, _THREAD_SIZE - 32 - PT_SIZE PTR_ADDU sp, $28 set_saved_sp sp, t0, t1 PTR_SUBU sp, 4 * SZREG # init stack pointer diff --git a/arch/mips/kernel/irq_txx9.c b/arch/mips/kernel/irq_txx9.c index a4d1462c27f7..9b78029bea70 100644 --- a/arch/mips/kernel/irq_txx9.c +++ b/arch/mips/kernel/irq_txx9.c @@ -1,6 +1,4 @@ /* - * linux/arch/mips/kernel/irq_txx9.c - * * Based on linux/arch/mips/jmr3927/rbhma3100/irq.c, * linux/arch/mips/tx4927/common/tx4927_irq.c, * linux/arch/mips/tx4938/common/irq.c diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c index fd6e51224034..f2397f00db43 100644 --- a/arch/mips/kernel/kspd.c +++ b/arch/mips/kernel/kspd.c @@ -31,7 +31,7 @@ #include <asm/rtlx.h> #include <asm/kspd.h> -static struct workqueue_struct *workqueue = NULL; +static struct workqueue_struct *workqueue; static struct work_struct work; extern unsigned long cpu_khz; @@ -58,7 +58,7 @@ struct mtsp_syscall_generic { }; static struct list_head kspd_notifylist; -static int sp_stopping = 0; +static int sp_stopping; /* these should match with those in the SDE kit */ #define MTSP_SYSCALL_BASE 0 @@ -328,7 +328,7 @@ static void sp_cleanup(void) sys_chdir("/"); } -static int channel_open = 0; +static int channel_open; /* the work handler */ static void sp_work(struct work_struct *unused) diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c index 42461310b185..cbc6182b0065 100644 --- a/arch/mips/kernel/mips-mt-fpaff.c +++ b/arch/mips/kernel/mips-mt-fpaff.c @@ -18,7 +18,7 @@ cpumask_t mt_fpu_cpumask; static int fpaff_threshold = -1; -unsigned long mt_fpemul_threshold = 0; +unsigned long mt_fpemul_threshold; /* * Replacement functions for the sys_sched_setaffinity() and diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c index d01665a453f5..b2259e7cd829 100644 --- a/arch/mips/kernel/mips-mt.c +++ b/arch/mips/kernel/mips-mt.c @@ -125,10 +125,10 @@ void mips_mt_regdump(unsigned long mvpctl) local_irq_restore(flags); } -static int mt_opt_norps = 0; +static int mt_opt_norps; static int mt_opt_rpsctl = -1; static int mt_opt_nblsu = -1; -static int mt_opt_forceconfig7 = 0; +static int mt_opt_forceconfig7; static int mt_opt_config7 = -1; static int __init rps_disable(char *s) @@ -161,8 +161,8 @@ static int __init config7_set(char *str) __setup("config7=", config7_set); /* Experimental cache flush control parameters that should go away some day */ -int mt_protiflush = 0; -int mt_protdflush = 0; +int mt_protiflush; +int mt_protdflush; int mt_n_iflushes = 1; int mt_n_dflushes = 1; @@ -194,7 +194,7 @@ static int __init ndflush(char *s) } __setup("ndflush=", ndflush); -static unsigned int itc_base = 0; +static unsigned int itc_base; static int __init set_itc_base(char *str) { diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c index 3e9100dcc12d..6f51dda87fce 100644 --- a/arch/mips/kernel/module.c +++ b/arch/mips/kernel/module.c @@ -98,7 +98,8 @@ static int apply_r_mips_32_rela(struct module *me, u32 *location, Elf_Addr v) static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v) { if (v % 4) { - printk(KERN_ERR "module %s: dangerous relocation\n", me->name); + pr_err("module %s: dangerous R_MIPS_26 REL relocation\n", + me->name); return -ENOEXEC; } @@ -118,7 +119,8 @@ static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v) static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v) { if (v % 4) { - printk(KERN_ERR "module %s: dangerous relocation\n", me->name); + pr_err("module %s: dangerous R_MIPS_26 RELArelocation\n", + me->name); return -ENOEXEC; } @@ -222,7 +224,7 @@ static int apply_r_mips_lo16_rel(struct module *me, u32 *location, Elf_Addr v) return 0; out_danger: - printk(KERN_ERR "module %s: dangerous " "relocation\n", me->name); + pr_err("module %s: dangerous R_MIPS_LO16 REL relocation\n", me->name); return -ENOEXEC; } @@ -301,7 +303,7 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, /* This is the symbol it is referring to */ sym = (Elf_Sym *)sechdrs[symindex].sh_addr + ELF_MIPS_R_SYM(rel[i]); - if (!sym->st_value) { + if (IS_ERR_VALUE(sym->st_value)) { /* Ignore unresolved weak symbol */ if (ELF_ST_BIND(sym->st_info) == STB_WEAK) continue; @@ -341,7 +343,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, /* This is the symbol it is referring to */ sym = (Elf_Sym *)sechdrs[symindex].sh_addr + ELF_MIPS_R_SYM(rel[i]); - if (!sym->st_value) { + if (IS_ERR_VALUE(sym->st_value)) { /* Ignore unresolved weak symbol */ if (ELF_ST_BIND(sym->st_info) == STB_WEAK) continue; diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S index d52389672b06..3952b8323efa 100644 --- a/arch/mips/kernel/octeon_switch.S +++ b/arch/mips/kernel/octeon_switch.S @@ -36,9 +36,6 @@ .align 7 LEAF(resume) .set arch=octeon -#ifndef CONFIG_CPU_HAS_LLSC - sw zero, ll_bit -#endif mfc0 t1, CP0_STATUS LONG_S t1, THREAD_STATUS(a0) cpu_save_nonscratch a0 diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index e0a4ac18fa07..26109c4d5170 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c @@ -1,6 +1,4 @@ /* - * linux/arch/mips/kernel/proc.c - * * Copyright (C) 1995, 1996, 2001 Ralf Baechle * Copyright (C) 2001, 2004 MIPS Technologies, Inc. * Copyright (C) 2004 Maciej W. Rozycki diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index c09d681b7181..f3d73e1831c1 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -115,7 +115,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, { struct thread_info *ti = task_thread_info(p); struct pt_regs *childregs; - long childksp; + unsigned long childksp; p->set_child_tid = p->clear_child_tid = NULL; childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE - 32; @@ -132,6 +132,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, /* set up new TSS. */ childregs = (struct pt_regs *) childksp - 1; + /* Put the stack after the struct pt_regs. */ + childksp = (unsigned long) childregs; *childregs = *regs; childregs->regs[7] = 0; /* Clear error flag */ diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c index c4f9ac17474a..32644b4a0714 100644 --- a/arch/mips/kernel/ptrace32.c +++ b/arch/mips/kernel/ptrace32.c @@ -22,7 +22,6 @@ #include <linux/errno.h> #include <linux/ptrace.h> #include <linux/smp.h> -#include <linux/smp_lock.h> #include <linux/user.h> #include <linux/security.h> diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S index 656bde2e11b1..698414b7a253 100644 --- a/arch/mips/kernel/r2300_switch.S +++ b/arch/mips/kernel/r2300_switch.S @@ -46,9 +46,6 @@ * struct thread_info *next_ti) ) */ LEAF(resume) -#ifndef CONFIG_CPU_HAS_LLSC - sw zero, ll_bit -#endif mfc0 t1, CP0_STATUS sw t1, THREAD_STATUS(a0) cpu_save_nonscratch a0 diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index d9bfae53c43f..8893ee1a2368 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S @@ -45,9 +45,6 @@ */ .align 5 LEAF(resume) -#ifndef CONFIG_CPU_HAS_LLSC - sw zero, ll_bit -#endif mfc0 t1, CP0_STATUS LONG_S t1, THREAD_STATUS(a0) cpu_save_nonscratch a0 diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index 4ce93aa7b372..a10ebfdc28ae 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c @@ -57,7 +57,7 @@ static struct chan_waitqueues { } channel_wqs[RTLX_CHANNELS]; static struct vpe_notifications notify; -static int sp_stopping = 0; +static int sp_stopping; extern void *vpe_get_shared(int index); diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 20a86e08fd58..7c2de4f091c4 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -187,78 +187,6 @@ illegal_syscall: j o32_syscall_exit END(handle_sys) - LEAF(mips_atomic_set) - andi v0, a1, 3 # must be word aligned - bnez v0, bad_alignment - - lw v1, TI_ADDR_LIMIT($28) # in legal address range? - addiu a0, a1, 4 - or a0, a0, a1 - and a0, a0, v1 - bltz a0, bad_address - -#ifdef CONFIG_CPU_HAS_LLSC - /* Ok, this is the ll/sc case. World is sane :-) */ -1: ll v0, (a1) - move a0, a2 -2: sc a0, (a1) -#if R10000_LLSC_WAR - beqzl a0, 1b -#else - beqz a0, 1b -#endif - - .section __ex_table,"a" - PTR 1b, bad_stack - PTR 2b, bad_stack - .previous -#else - sw a1, 16(sp) - sw a2, 20(sp) - - move a0, sp - move a2, a1 - li a1, 1 - jal do_page_fault - - lw a1, 16(sp) - lw a2, 20(sp) - - /* - * At this point the page should be readable and writable unless - * there was no more memory available. - */ -1: lw v0, (a1) -2: sw a2, (a1) - - .section __ex_table,"a" - PTR 1b, no_mem - PTR 2b, no_mem - .previous -#endif - - sw zero, PT_R7(sp) # success - sw v0, PT_R2(sp) # result - - j o32_syscall_exit # continue like a normal syscall - -no_mem: li v0, -ENOMEM - jr ra - -bad_address: - li v0, -EFAULT - jr ra - -bad_alignment: - li v0, -EINVAL - jr ra - END(mips_atomic_set) - - LEAF(sys_sysmips) - beq a0, MIPS_ATOMIC_SET, mips_atomic_set - j _sys_sysmips - END(sys_sysmips) - LEAF(sys_syscall) subu t0, a0, __NR_O32_Linux # check syscall number sltiu v0, t0, __NR_O32_Linux_syscalls + 1 @@ -654,6 +582,7 @@ einval: li v0, -ENOSYS sys sys_pwritev 6 sys sys_rt_tgsigqueueinfo 4 sys sys_perf_counter_open 5 + sys sys_accept4 4 .endm /* We pre-compute the number of _instruction_ bytes needed to diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index b046130d4c5d..b97b993846d6 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -124,78 +124,6 @@ illegal_syscall: j n64_syscall_exit END(handle_sys64) - LEAF(mips_atomic_set) - andi v0, a1, 3 # must be word aligned - bnez v0, bad_alignment - - LONG_L v1, TI_ADDR_LIMIT($28) # in legal address range? - LONG_ADDIU a0, a1, 4 - or a0, a0, a1 - and a0, a0, v1 - bltz a0, bad_address - -#ifdef CONFIG_CPU_HAS_LLSC - /* Ok, this is the ll/sc case. World is sane :-) */ -1: ll v0, (a1) - move a0, a2 -2: sc a0, (a1) -#if R10000_LLSC_WAR - beqzl a0, 1b -#else - beqz a0, 1b -#endif - - .section __ex_table,"a" - PTR 1b, bad_stack - PTR 2b, bad_stack - .previous -#else - sw a1, 16(sp) - sw a2, 20(sp) - - move a0, sp - move a2, a1 - li a1, 1 - jal do_page_fault - - lw a1, 16(sp) - lw a2, 20(sp) - - /* - * At this point the page should be readable and writable unless - * there was no more memory available. - */ -1: lw v0, (a1) -2: sw a2, (a1) - - .section __ex_table,"a" - PTR 1b, no_mem - PTR 2b, no_mem - .previous -#endif - - sd zero, PT_R7(sp) # success - sd v0, PT_R2(sp) # result - - j n64_syscall_exit # continue like a normal syscall - -no_mem: li v0, -ENOMEM - jr ra - -bad_address: - li v0, -EFAULT - jr ra - -bad_alignment: - li v0, -EINVAL - jr ra - END(mips_atomic_set) - - LEAF(sys_sysmips) - beq a0, MIPS_ATOMIC_SET, mips_atomic_set - j _sys_sysmips - END(sys_sysmips) - .align 3 sys_call_table: PTR sys_read /* 5000 */ @@ -491,4 +419,5 @@ sys_call_table: PTR sys_pwritev /* 5390 */ PTR sys_rt_tgsigqueueinfo PTR sys_perf_counter_open + PTR sys_accept4 .size sys_call_table,.-sys_call_table diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 15874f9812cc..1a6ae124635b 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -164,7 +164,7 @@ EXPORT(sysn32_call_table) PTR sys_connect PTR sys_accept PTR sys_sendto - PTR sys_recvfrom + PTR compat_sys_recvfrom PTR compat_sys_sendmsg /* 6045 */ PTR compat_sys_recvmsg PTR sys_shutdown @@ -417,4 +417,5 @@ EXPORT(sysn32_call_table) PTR sys_pwritev PTR compat_sys_rt_tgsigqueueinfo /* 5295 */ PTR sys_perf_counter_open + PTR sys_accept4 .size sysn32_call_table,.-sysn32_call_table diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 781e0f1e9533..cd31087a651f 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -378,8 +378,8 @@ sys_call_table: PTR sys_getsockname PTR sys_getsockopt PTR sys_listen - PTR sys_recv /* 4175 */ - PTR sys_recvfrom + PTR compat_sys_recv /* 4175 */ + PTR compat_sys_recvfrom PTR compat_sys_recvmsg PTR sys_send PTR compat_sys_sendmsg @@ -537,4 +537,5 @@ sys_call_table: PTR compat_sys_pwritev PTR compat_sys_rt_tgsigqueueinfo PTR sys_perf_counter_open + PTR sys_accept4 .size sys_call_table,.-sys_call_table diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 2950b97253b7..2b290d70083e 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -441,7 +441,7 @@ static void __init bootmem_init(void) * initialization hook for anything else was introduced. */ -static int usermem __initdata = 0; +static int usermem __initdata; static int __init early_parse_mem(char *p) { diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 830c5ef9932b..6254041b942f 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -21,6 +21,7 @@ #include <linux/compiler.h> #include <linux/syscalls.h> #include <linux/uaccess.h> +#include <linux/tracehook.h> #include <asm/abi.h> #include <asm/asm.h> @@ -700,4 +701,11 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused, /* deal with pending signal delivery */ if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) do_signal(regs); + + if (thread_info_flags & _TIF_NOTIFY_RESUME) { + clear_thread_flag(TIF_NOTIFY_RESUME); + tracehook_notify_resume(regs); + if (current->replacement_session_keyring) + key_replace_session_keyring(); + } } diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index bc7d9b05e2f4..64668a93248b 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -32,6 +32,7 @@ #include <linux/cpumask.h> #include <linux/cpu.h> #include <linux/err.h> +#include <linux/smp.h> #include <asm/atomic.h> #include <asm/cpu.h> @@ -49,8 +50,6 @@ volatile cpumask_t cpu_callin_map; /* Bitmask of started secondaries */ int __cpu_number_map[NR_CPUS]; /* Map physical to logical */ int __cpu_logical_map[NR_CPUS]; /* Map logical to physical */ -extern void cpu_idle(void); - /* Number of TCs (or siblings in Intel speak) per CPU core */ int smp_num_siblings = 1; EXPORT_SYMBOL(smp_num_siblings); diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 8a0626cbb108..1a466baf0edf 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -95,14 +95,14 @@ void init_smtc_stats(void); /* Global SMTC Status */ -unsigned int smtc_status = 0; +unsigned int smtc_status; /* Boot command line configuration overrides */ static int vpe0limit; -static int ipibuffers = 0; -static int nostlb = 0; -static int asidmask = 0; +static int ipibuffers; +static int nostlb; +static int asidmask; unsigned long smtc_asid_mask = 0xff; static int __init vpe0tcs(char *str) @@ -151,7 +151,7 @@ __setup("asidmask=", asidmask_set); #ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG -static int hang_trig = 0; +static int hang_trig; static int __init hangtrig_enable(char *s) { @@ -465,11 +465,8 @@ void smtc_prepare_cpus(int cpus) smtc_configure_tlb(); for (tc = 0, vpe = 0 ; (vpe < nvpe) && (tc < ntc) ; vpe++) { - /* - * Set the MVP bits. - */ - settc(tc); - write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_MVP); + if (tcpervpe[vpe] == 0) + continue; if (vpe != 0) printk(", "); printk("VPE %d: TC", vpe); @@ -488,6 +485,12 @@ void smtc_prepare_cpus(int cpus) } if (vpe != 0) { /* + * Allow this VPE to control others. + */ + write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | + VPECONF0_MVP); + + /* * Clear any stale software interrupts from VPE's Cause */ write_vpe_c0_cause(0); diff --git a/arch/mips/kernel/stacktrace.c b/arch/mips/kernel/stacktrace.c index 58f5cd76c8c3..d52ff77baf3f 100644 --- a/arch/mips/kernel/stacktrace.c +++ b/arch/mips/kernel/stacktrace.c @@ -1,6 +1,4 @@ /* - * arch/mips/kernel/stacktrace.c - * * Stack trace management functions * * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp> diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 8cf384644040..3fe1fcfa2e73 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -28,7 +28,9 @@ #include <linux/compiler.h> #include <linux/module.h> #include <linux/ipc.h> +#include <linux/uaccess.h> +#include <asm/asm.h> #include <asm/branch.h> #include <asm/cachectl.h> #include <asm/cacheflush.h> @@ -290,12 +292,116 @@ SYSCALL_DEFINE1(set_thread_area, unsigned long, addr) return 0; } -asmlinkage int _sys_sysmips(long cmd, long arg1, long arg2, long arg3) +static inline int mips_atomic_set(struct pt_regs *regs, + unsigned long addr, unsigned long new) { + unsigned long old, tmp; + unsigned int err; + + if (unlikely(addr & 3)) + return -EINVAL; + + if (unlikely(!access_ok(VERIFY_WRITE, addr, 4))) + return -EINVAL; + + if (cpu_has_llsc && R10000_LLSC_WAR) { + __asm__ __volatile__ ( + " li %[err], 0 \n" + "1: ll %[old], (%[addr]) \n" + " move %[tmp], %[new] \n" + "2: sc %[tmp], (%[addr]) \n" + " beqzl %[tmp], 1b \n" + "3: \n" + " .section .fixup,\"ax\" \n" + "4: li %[err], %[efault] \n" + " j 3b \n" + " .previous \n" + " .section __ex_table,\"a\" \n" + " "STR(PTR)" 1b, 4b \n" + " "STR(PTR)" 2b, 4b \n" + " .previous \n" + : [old] "=&r" (old), + [err] "=&r" (err), + [tmp] "=&r" (tmp) + : [addr] "r" (addr), + [new] "r" (new), + [efault] "i" (-EFAULT) + : "memory"); + } else if (cpu_has_llsc) { + __asm__ __volatile__ ( + " li %[err], 0 \n" + "1: ll %[old], (%[addr]) \n" + " move %[tmp], %[new] \n" + "2: sc %[tmp], (%[addr]) \n" + " bnez %[tmp], 4f \n" + "3: \n" + " .subsection 2 \n" + "4: b 1b \n" + " .previous \n" + " \n" + " .section .fixup,\"ax\" \n" + "5: li %[err], %[efault] \n" + " j 3b \n" + " .previous \n" + " .section __ex_table,\"a\" \n" + " "STR(PTR)" 1b, 5b \n" + " "STR(PTR)" 2b, 5b \n" + " .previous \n" + : [old] "=&r" (old), + [err] "=&r" (err), + [tmp] "=&r" (tmp) + : [addr] "r" (addr), + [new] "r" (new), + [efault] "i" (-EFAULT) + : "memory"); + } else { + do { + preempt_disable(); + ll_bit = 1; + ll_task = current; + preempt_enable(); + + err = __get_user(old, (unsigned int *) addr); + err |= __put_user(new, (unsigned int *) addr); + if (err) + break; + rmb(); + } while (!ll_bit); + } + + if (unlikely(err)) + return err; + + regs->regs[2] = old; + regs->regs[7] = 0; /* No error */ + + /* + * Don't let your children do this ... + */ + __asm__ __volatile__( + " move $29, %0 \n" + " j syscall_exit \n" + : /* no outputs */ + : "r" (regs)); + + /* unreached. Honestly. */ + while (1); +} + +save_static_function(sys_sysmips); +static int __used noinline +_sys_sysmips(nabi_no_regargs struct pt_regs regs) +{ + long cmd, arg1, arg2, arg3; + + cmd = regs.regs[4]; + arg1 = regs.regs[5]; + arg2 = regs.regs[6]; + arg3 = regs.regs[7]; + switch (cmd) { case MIPS_ATOMIC_SET: - printk(KERN_CRIT "How did I get here?\n"); - return -EINVAL; + return mips_atomic_set(®s, arg1, arg2); case MIPS_FIXADE: if (arg1 & ~3) diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 08f1edf355e8..0a18b4c62afb 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -466,9 +466,8 @@ asmlinkage void do_be(struct pt_regs *regs) * The ll_bit is cleared by r*_switch.S */ -unsigned long ll_bit; - -static struct task_struct *ll_task = NULL; +unsigned int ll_bit; +struct task_struct *ll_task; static inline int simulate_ll(struct pt_regs *regs, unsigned int opcode) { diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 58738c8d754f..2769bed3d2af 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -1,4 +1,5 @@ #include <asm/asm-offsets.h> +#include <asm/page.h> #include <asm-generic/vmlinux.lds.h> #undef mips @@ -42,13 +43,7 @@ SECTIONS } :text = 0 _etext = .; /* End of text section */ - /* Exception table */ - . = ALIGN(16); - __ex_table : { - __start___ex_table = .; - *(__ex_table) - __stop___ex_table = .; - } + EXCEPTION_TABLE(16) /* Exception table for data bus errors */ __dbe_table : { @@ -65,20 +60,10 @@ SECTIONS /* writeable */ .data : { /* Data */ . = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */ - /* - * This ALIGN is needed as a workaround for a bug a - * gcc bug upto 4.1 which limits the maximum alignment - * to at most 32kB and results in the following - * warning: - * - * CC arch/mips/kernel/init_task.o - * arch/mips/kernel/init_task.c:30: warning: alignment - * of ‘init_thread_union’ is greater than maximum - * object file alignment. Using 32768 - */ - . = ALIGN(_PAGE_SIZE); - *(.data.init_task) + INIT_TASK_DATA(PAGE_SIZE) + NOSAVE_DATA + CACHELINE_ALIGNED_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT) DATA_DATA CONSTRUCTORS } @@ -95,51 +80,13 @@ SECTIONS .sdata : { *(.sdata) } - - . = ALIGN(_PAGE_SIZE); - .data_nosave : { - __nosave_begin = .; - *(.data.nosave) - } - . = ALIGN(_PAGE_SIZE); - __nosave_end = .; - - . = ALIGN(1 << CONFIG_MIPS_L1_CACHE_SHIFT); - .data.cacheline_aligned : { - *(.data.cacheline_aligned) - } _edata = .; /* End of data section */ /* will be freed after init */ - . = ALIGN(_PAGE_SIZE); /* Init code and data */ + . = ALIGN(PAGE_SIZE); /* Init code and data */ __init_begin = .; - .init.text : { - _sinittext = .; - INIT_TEXT - _einittext = .; - } - .init.data : { - INIT_DATA - } - . = ALIGN(16); - .init.setup : { - __setup_start = .; - *(.init.setup) - __setup_end = .; - } - - .initcall.init : { - __initcall_start = .; - INITCALLS - __initcall_end = .; - } - - .con_initcall.init : { - __con_initcall_start = .; - *(.con_initcall.init) - __con_initcall_end = .; - } - SECURITY_INIT + INIT_TEXT_SECTION(PAGE_SIZE) + INIT_DATA_SECTION(16) /* .exit.text is discarded at runtime, not link time, to deal with * references from .rodata @@ -150,43 +97,16 @@ SECTIONS .exit.data : { EXIT_DATA } -#if defined(CONFIG_BLK_DEV_INITRD) - . = ALIGN(_PAGE_SIZE); - .init.ramfs : { - __initramfs_start = .; - *(.init.ramfs) - __initramfs_end = .; - } -#endif - PERCPU(_PAGE_SIZE) - . = ALIGN(_PAGE_SIZE); + + PERCPU(PAGE_SIZE) + . = ALIGN(PAGE_SIZE); __init_end = .; /* freed after init ends here */ - __bss_start = .; /* BSS */ - .sbss : { - *(.sbss) - *(.scommon) - } - .bss : { - *(.bss) - *(COMMON) - } - __bss_stop = .; + BSS_SECTION(0, 0, 0) _end = . ; - /* Sections to be discarded */ - /DISCARD/ : { - *(.exitcall.exit) - - /* ABI crap starts here */ - *(.MIPS.options) - *(.options) - *(.pdr) - *(.reginfo) - } - /* These mark the ABI of the kernel for debuggers. */ .mdebug.abi32 : { KEEP(*(.mdebug.abi32)) @@ -212,4 +132,14 @@ SECTIONS *(.gptab.bss) *(.gptab.sbss) } + + /* Sections to be discarded */ + DISCARDS + /DISCARD/ : { + /* ABI crap starts here */ + *(.MIPS.options) + *(.options) + *(.pdr) + *(.reginfo) + } } diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 07b9ec2c6e3d..eb6c4c5b7fbe 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c @@ -73,8 +73,8 @@ static int major; static const int minor = 1; /* fixed for now */ #ifdef CONFIG_MIPS_APSP_KSPD - static struct kspd_notifications kspd_events; -static int kspd_events_reqd = 0; +static struct kspd_notifications kspd_events; +static int kspd_events_reqd; #endif /* grab the likely amount of memory we will need. */ @@ -155,10 +155,9 @@ struct { }; static void release_progmem(void *ptr); -extern void save_gp_address(unsigned int secbase, unsigned int rel); /* get the vpe associated with this minor */ -struct vpe *get_vpe(int minor) +static struct vpe *get_vpe(int minor) { struct vpe *v; @@ -174,7 +173,7 @@ struct vpe *get_vpe(int minor) } /* get the vpe associated with this minor */ -struct tc *get_tc(int index) +static struct tc *get_tc(int index) { struct tc *t; @@ -186,20 +185,8 @@ struct tc *get_tc(int index) return NULL; } -struct tc *get_tc_unused(void) -{ - struct tc *t; - - list_for_each_entry(t, &vpecontrol.tc_list, list) { - if (t->state == TC_STATE_UNUSED) - return t; - } - - return NULL; -} - /* allocate a vpe and associate it with this minor (or index) */ -struct vpe *alloc_vpe(int minor) +static struct vpe *alloc_vpe(int minor) { struct vpe *v; @@ -216,7 +203,7 @@ struct vpe *alloc_vpe(int minor) } /* allocate a tc. At startup only tc0 is running, all other can be halted. */ -struct tc *alloc_tc(int index) +static struct tc *alloc_tc(int index) { struct tc *tc; @@ -232,7 +219,7 @@ out: } /* clean up and free everything */ -void release_vpe(struct vpe *v) +static void release_vpe(struct vpe *v) { list_del(&v->list); if (v->load_addr) @@ -240,7 +227,7 @@ void release_vpe(struct vpe *v) kfree(v); } -void dump_mtregs(void) +static void dump_mtregs(void) { unsigned long val; @@ -327,7 +314,8 @@ static void layout_sections(struct module *mod, const Elf_Ehdr * hdr, || (s->sh_flags & masks[m][1]) || s->sh_entsize != ~0UL) continue; - s->sh_entsize = get_offset(&mod->core_size, s); + s->sh_entsize = + get_offset((unsigned long *)&mod->core_size, s); } if (m == 0) @@ -461,16 +449,15 @@ static int apply_r_mips_lo16(struct module *me, uint32_t *location, { unsigned long insnlo = *location; Elf32_Addr val, vallo; + struct mips_hi16 *l, *next; /* Sign extend the addend we extract from the lo insn. */ vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000; if (mips_hi16_list != NULL) { - struct mips_hi16 *l; l = mips_hi16_list; while (l != NULL) { - struct mips_hi16 *next; unsigned long insn; /* @@ -480,7 +467,7 @@ static int apply_r_mips_lo16(struct module *me, uint32_t *location, printk(KERN_DEBUG "VPE loader: " "apply_r_mips_lo16/hi16: \t" "inconsistent value information\n"); - return -ENOEXEC; + goto out_free; } /* @@ -518,6 +505,16 @@ static int apply_r_mips_lo16(struct module *me, uint32_t *location, *location = insnlo; return 0; + +out_free: + while (l != NULL) { + next = l->next; + kfree(l); + l = next; + } + mips_hi16_list = NULL; + + return -ENOEXEC; } static int (*reloc_handlers[]) (struct module *me, uint32_t *location, @@ -541,7 +538,7 @@ static char *rstrs[] = { [R_MIPS_PC16] = "MIPS_PC16" }; -int apply_relocations(Elf32_Shdr *sechdrs, +static int apply_relocations(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, unsigned int relsec, @@ -586,7 +583,7 @@ int apply_relocations(Elf32_Shdr *sechdrs, return 0; } -void save_gp_address(unsigned int secbase, unsigned int rel) +static inline void save_gp_address(unsigned int secbase, unsigned int rel) { gp_addr = secbase + rel; gp_offs = gp_addr - (secbase & 0xffff0000); |