diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-06-03 09:23:20 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1997-06-03 09:23:20 +0000 |
commit | ac5ff8f4a72f7b4e66f73c3c6cb9fe7758cf6f12 (patch) | |
tree | 9fc7f8ce32e0d9a4aa055b2a58a05a5d727b333c /arch | |
parent | 52662ff3e66770fd7e4fc508c91056d29c08bff0 (diff) |
Sync with Linux 2.1.42.
Diffstat (limited to 'arch')
-rw-r--r-- | arch/alpha/Makefile | 2 | ||||
-rw-r--r-- | arch/alpha/kernel/entry.S | 3 | ||||
-rw-r--r-- | arch/i386/boot/tools/build.c | 5 | ||||
-rw-r--r-- | arch/i386/kernel/i386_ksyms.c | 1 | ||||
-rw-r--r-- | arch/m68k/amiga/config.c | 1 | ||||
-rw-r--r-- | arch/sparc/kernel/setup.c | 3 | ||||
-rw-r--r-- | arch/sparc/lib/blockops.S | 17 | ||||
-rw-r--r-- | arch/sparc/mm/hypersparc.S | 52 | ||||
-rw-r--r-- | arch/sparc/mm/srmmu.c | 13 | ||||
-rw-r--r-- | arch/sparc/prom/memory.c | 9 | ||||
-rw-r--r-- | arch/sparc64/kernel/Makefile | 6 | ||||
-rw-r--r-- | arch/sparc64/kernel/entry.S | 78 | ||||
-rw-r--r-- | arch/sparc64/kernel/etrap.S | 56 | ||||
-rw-r--r-- | arch/sparc64/kernel/hack.S | 24 | ||||
-rw-r--r-- | arch/sparc64/kernel/irq.c | 10 | ||||
-rw-r--r-- | arch/sparc64/kernel/process.c | 3 | ||||
-rw-r--r-- | arch/sparc64/kernel/rtrap.S | 70 | ||||
-rw-r--r-- | arch/sparc64/kernel/setup.c | 32 | ||||
-rw-r--r-- | arch/sparc64/kernel/signal.c | 19 | ||||
-rw-r--r-- | arch/sparc64/kernel/signal32.c | 15 | ||||
-rw-r--r-- | arch/sparc64/kernel/sys_sparc32.c | 261 | ||||
-rw-r--r-- | arch/sparc64/kernel/systbls.S | 10 | ||||
-rw-r--r-- | arch/sparc64/kernel/traps.c | 305 | ||||
-rw-r--r-- | arch/sparc64/mm/fault.c | 8 | ||||
-rw-r--r-- | arch/sparc64/mm/init.c | 10 |
25 files changed, 781 insertions, 232 deletions
diff --git a/arch/alpha/Makefile b/arch/alpha/Makefile index 58fd53354..c12783c92 100644 --- a/arch/alpha/Makefile +++ b/arch/alpha/Makefile @@ -10,7 +10,7 @@ NM := nm -B -LINKFLAGS = -static -T arch/alpha/vmlinux.lds -N +LINKFLAGS = -static -T arch/alpha/vmlinux.lds CFLAGS := $(CFLAGS) -pipe -mno-fp-regs -ffixed-8 HEAD := arch/alpha/kernel/head.o diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index af26f8996..8f896195d 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S @@ -247,6 +247,7 @@ __kernel_thread: bis $10,$10,$16 /* get arg */ bic $30,$8,$8 /* get current */ jsr $26,($27) + ldgp $29,0($26) bis $0,$0,$16 jsr $26,sys_exit call_pal PAL_halt @@ -519,6 +520,7 @@ entSys: beq $4,1f ldq $27,0($5) 1: jsr $26,($27),do_entSys + ldgp $29,0($26) blt $0,syscall_error /* the call failed */ stq $0,0($30) stq $31,72($30) /* a3=0 => no error */ @@ -578,6 +580,7 @@ strace: beq $1,1f ldq $27,0($2) 1: jsr $26,($27),do_entSys + ldgp $29,0($26) /* check return.. */ blt $0,strace_error /* the call failed */ diff --git a/arch/i386/boot/tools/build.c b/arch/i386/boot/tools/build.c index 039f27003..3998daf84 100644 --- a/arch/i386/boot/tools/build.c +++ b/arch/i386/boot/tools/build.c @@ -1,5 +1,5 @@ /* - * arch/i386/boot/tools/build.c + * $Id: build.c,v 1.5 1997/05/19 12:29:58 mj Exp $ * * Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 1997 Martin Mares @@ -170,7 +170,8 @@ int main(int argc, char ** argv) fprintf (stderr, "System is %d kB\n", sz/1024); sys_size = (sz + 15) / 16; if (sys_size > (is_big_kernel ? 0xffff : DEF_SYSSIZE)) - die("System is too big"); + die("System is too big. Try using %smodules.", + is_big_kernel ? "" : "bzImage or "); while (sz > 0) { int l, n; diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c index daa6baf42..a711d9a40 100644 --- a/arch/i386/kernel/i386_ksyms.c +++ b/arch/i386/kernel/i386_ksyms.c @@ -25,6 +25,7 @@ EXPORT_SYMBOL(drive_info); #endif /* platform dependent support */ +EXPORT_SYMBOL(x86); EXPORT_SYMBOL(EISA_bus); EXPORT_SYMBOL(MCA_bus); EXPORT_SYMBOL(wp_works_ok); diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c index 08396a5bc..7b6bd208f 100644 --- a/arch/m68k/amiga/config.c +++ b/arch/m68k/amiga/config.c @@ -12,7 +12,6 @@ * Miscellaneous Amiga stuff */ -#include <stdarg.h> #include <linux/config.h> #include <linux/types.h> #include <linux/kernel.h> diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c index aa204db06..a6b3f9e07 100644 --- a/arch/sparc/kernel/setup.c +++ b/arch/sparc/kernel/setup.c @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.84 1997/05/08 17:45:16 davem Exp $ +/* $Id: setup.c,v 1.85 1997/05/27 06:45:54 davem Exp $ * linux/arch/sparc/kernel/setup.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -79,7 +79,6 @@ asmlinkage void sys_sync(void); /* it's really int */ void prom_sync_me(void) { unsigned long prom_tbr, flags; - int cpu = smp_processor_id(); #ifdef __SMP__ global_irq_holder = NO_PROC_ID; diff --git a/arch/sparc/lib/blockops.S b/arch/sparc/lib/blockops.S index c11ab1b20..a5a4bffad 100644 --- a/arch/sparc/lib/blockops.S +++ b/arch/sparc/lib/blockops.S @@ -1,4 +1,4 @@ -/* $Id: blockops.S,v 1.6 1997/05/03 02:01:54 davem Exp $ +/* $Id: blockops.S,v 1.7 1997/05/20 07:58:28 jj Exp $ * blockops.S: Common block zero optimized routines. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -45,8 +45,11 @@ .text .align 4 + .globl C_LABEL(bzero_1page), C_LABEL(__copy_1page) -generic_bzero_1page: +C_LABEL(bzero_1page): +/* NOTE: If you change the number of insns of this routine, please check + * arch/sparc/mm/hypersparc.S */ /* %o0 = buf */ or %g0, %g0, %g1 or %o0, %g0, %o1 @@ -63,7 +66,9 @@ generic_bzero_1page: retl nop -__generic_copy_1page: +C_LABEL(__copy_1page): +/* NOTE: If you change the number of insns of this routine, please check + * arch/sparc/mm/hypersparc.S */ /* %o0 = dst, %o1 = src */ or %g0, 0x10, %g1 1: @@ -82,9 +87,3 @@ __generic_copy_1page: retl nop - - .data - .align 4 - .globl C_LABEL(bzero_1page), C_LABEL(__copy_1page) -C_LABEL(bzero_1page): .word generic_bzero_1page -C_LABEL(__copy_1page): .word __generic_copy_1page diff --git a/arch/sparc/mm/hypersparc.S b/arch/sparc/mm/hypersparc.S index 62e2022e0..e6ba7b235 100644 --- a/arch/sparc/mm/hypersparc.S +++ b/arch/sparc/mm/hypersparc.S @@ -1,4 +1,4 @@ -/* $Id: hypersparc.S,v 1.7 1997/05/03 05:09:12 davem Exp $ +/* $Id: hypersparc.S,v 1.10 1997/05/27 19:29:58 jj Exp $ * hypersparc.S: High speed Hypersparc mmu/cache operations. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -9,6 +9,7 @@ #include <asm/asi.h> #include <asm/page.h> #include <asm/pgtsrmmu.h> +#include <linux/init.h> #define WINDOW_FLUSH(tmp1, tmp2) \ mov 0, tmp1; \ @@ -335,17 +336,19 @@ hypersparc_flush_tlb_page_out: retl sta %g5, [%g1] ASI_M_MMUREGS + __INIT + /* High speed page clear/copy. */ - .globl hypersparc_bzero_1page, hypersparc_copy_1page hypersparc_bzero_1page: +/* NOTE: This routine has to be shorter than 40insns --jj */ clr %g1 mov 32, %g2 - add %g2, %g2, %g3 - add %g2, %g3, %g4 - add %g2, %g4, %g5 - add %g2, %g5, %g7 - add %g2, %g7, %o2 - add %g2, %o2, %o3 + mov 64, %g3 + mov 96, %g4 + mov 128, %g5 + mov 160, %g7 + mov 192, %o2 + mov 224, %o3 mov 16, %o1 1: stda %g0, [%o0 + %g0] ASI_M_BFILL @@ -364,6 +367,7 @@ hypersparc_bzero_1page: nop hypersparc_copy_1page: +/* NOTE: This routine has to be shorter than 70insns --jj */ sub %o1, %o0, %o2 ! difference mov 16, %g1 1: @@ -388,3 +392,35 @@ hypersparc_copy_1page: retl nop + + .globl hypersparc_setup_blockops +hypersparc_setup_blockops: + sethi %hi(bzero_1page), %o0 + or %o0, %lo(bzero_1page), %o0 + sethi %hi(hypersparc_bzero_1page), %o1 + or %o1, %lo(hypersparc_bzero_1page), %o1 + sethi %hi(hypersparc_copy_1page), %o2 + or %o2, %lo(hypersparc_copy_1page), %o2 + ld [%o1], %o4 +1: + add %o1, 4, %o1 + st %o4, [%o0] + add %o0, 4, %o0 + cmp %o1, %o2 + bne 1b + ld [%o1], %o4 + sethi %hi(__copy_1page), %o0 + or %o0, %lo(__copy_1page), %o0 + sethi %hi(hypersparc_setup_blockops), %o2 + or %o2, %lo(hypersparc_setup_blockops), %o2 + ld [%o1], %o4 +1: + add %o1, 4, %o1 + st %o4, [%o0] + add %o0, 4, %o0 + cmp %o1, %o2 + bne 1b + ld [%o1], %o4 + sta %g0, [%g0] ASI_M_FLUSH_IWHOLE + retl + nop diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index b04064efb..7420b98cb 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -1,4 +1,4 @@ -/* $Id: srmmu.c,v 1.146 1997/05/18 21:11:09 davem Exp $ +/* $Id: srmmu.c,v 1.147 1997/05/20 07:58:42 jj Exp $ * srmmu.c: SRMMU specific routines for memory management. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -1239,8 +1239,7 @@ extern void hypersparc_flush_tlb_all(void); extern void hypersparc_flush_tlb_mm(struct mm_struct *mm); extern void hypersparc_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end); extern void hypersparc_flush_tlb_page(struct vm_area_struct *vma, unsigned long page); -extern void hypersparc_bzero_1page(void *); -extern void hypersparc_copy_1page(void *, const void *); +extern void hypersparc_setup_blockops(void); static void srmmu_set_pte_nocache_hyper(pte_t *ptep, pte_t pteval) { @@ -2411,13 +2410,7 @@ __initfunc(static void init_hypersparc(void)) sparc_update_rootmmu_dir = hypersparc_update_rootmmu_dir; poke_srmmu = poke_hypersparc; - /* High performance page copy/clear. */ - { extern void (*__copy_1page)(void *, const void *); - extern void (*bzero_1page)(void *); - - __copy_1page = hypersparc_copy_1page; - bzero_1page = hypersparc_bzero_1page; - } + hypersparc_setup_blockops(); } static void poke_cypress(void) diff --git a/arch/sparc/prom/memory.c b/arch/sparc/prom/memory.c index e2a809017..b53bd17ea 100644 --- a/arch/sparc/prom/memory.c +++ b/arch/sparc/prom/memory.c @@ -1,4 +1,4 @@ -/* $Id: memory.c,v 1.10 1997/03/18 17:58:27 jj Exp $ +/* $Id: memory.c,v 1.12 1997/05/27 06:45:57 davem Exp $ * memory.c: Prom routine for acquiring various bits of information * about RAM on the machine, both virtual and physical. * @@ -116,7 +116,7 @@ __initfunc(void prom_meminit(void)) num_regs = (num_regs/sizeof(struct linux_prom_registers)); for(iter=0; iter<num_regs; iter++) { prom_phys_avail[iter].start_adr = - prom_reg_memlist[iter].phys_addr; + (char *) prom_reg_memlist[iter].phys_addr; prom_phys_avail[iter].num_bytes = (unsigned long) prom_reg_memlist[iter].reg_size; prom_phys_avail[iter].theres_more = @@ -130,7 +130,7 @@ __initfunc(void prom_meminit(void)) num_regs = (num_regs/sizeof(struct linux_prom_registers)); for(iter=0; iter<num_regs; iter++) { prom_phys_total[iter].start_adr = - prom_reg_memlist[iter].phys_addr; + (char *) prom_reg_memlist[iter].phys_addr; prom_phys_total[iter].num_bytes = (unsigned long) prom_reg_memlist[iter].reg_size; prom_phys_total[iter].theres_more = @@ -150,7 +150,7 @@ __initfunc(void prom_meminit(void)) */ for(iter=0; iter<num_regs; iter++) { prom_prom_taken[iter].start_adr = - prom_reg_memlist[iter].phys_addr; + (char *) prom_reg_memlist[iter].phys_addr; prom_prom_taken[iter].num_bytes = (unsigned long) prom_reg_memlist[iter].reg_size; prom_prom_taken[iter].theres_more = @@ -193,6 +193,7 @@ __initfunc(void prom_meminit(void)) prom_sortmemlist(prom_prom_taken); prom_sortmemlist(prom_phys_avail); #endif + default: break; }; diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index 4a07295e1..199360a5f 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.20 1997/05/18 08:42:11 davem Exp $ +# $Id: Makefile,v 1.22 1997/05/27 19:30:17 jj Exp $ # Makefile for the linux kernel. # # Note! Dependencies are done automagically by 'make dep', which also @@ -18,11 +18,11 @@ all: kernel.o head.o init_task.o O_TARGET := kernel.o O_OBJS := etrap.o rtrap.o hack.o process.o setup.o cpu.o idprom.o \ systbls.o traps.o entry.o devices.o auxio.o ioport.o \ - irq.o time.o sys_sparc.o signal.o winfixup.o + irq.o ptrace.o time.o sys_sparc.o signal.o winfixup.o OX_OBJS := sparc64_ksyms.o ifdef CONFIG_SPARC32_COMPAT - O_OBJS += sys_sparc32.o signal32.o + O_OBJS += sys_sparc32.o signal32.o ioctl32.o endif ifdef CONFIG_BINFMT_ELF32 diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index 589d1661a..579fbb4c2 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -1,4 +1,4 @@ -/* $Id: entry.S,v 1.21 1997/05/18 10:04:44 davem Exp $ +/* $Id: entry.S,v 1.27 1997/05/27 19:30:11 jj Exp $ * arch/sparc64/kernel/entry.S: Sparc64 trap low-level entry points. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -18,6 +18,8 @@ #include <asm/signal.h> #include <asm/pgtable.h> +/* define SYSCALL_TRACING */ + #define curptr g6 #define NR_SYSCALLS 256 /* Each OS is different... */ @@ -52,6 +54,11 @@ sparc64_dtlb_prot_catch: b,a,pt %xcc, 1f sparc64_dtlb_refbit_catch: + srlx %g5, 9, %g4 + and %g4, ((_PAGE_PRESENT | _PAGE_READ) >> 9), %g4 + cmp %g4, ((_PAGE_PRESENT | _PAGE_READ) >> 9) + be,a,pt %xcc, 2f + mov 1, %g4 wr %g0, ASI_DMMU, %asi rdpr %pstate, %g1 wrpr %g1, PSTATE_AG|PSTATE_MG, %pstate @@ -75,6 +82,11 @@ sparc64_dtlb_refbit_catch: ba,a,pt %xcc, rtrap sparc64_itlb_refbit_catch: + srlx %g5, 9, %g4 + and %g4, ((_PAGE_PRESENT | _PAGE_READ) >> 9), %g4 + cmp %g4, ((_PAGE_PRESENT | _PAGE_READ) >> 9) + be,a,pt %xcc, 3f + mov 1, %g4 rdpr %pstate, %g1 wrpr %g1, PSTATE_AG|PSTATE_MG, %pstate ba,pt %xcc, etrap @@ -89,6 +101,22 @@ sparc64_itlb_refbit_catch: add %sp, STACK_BIAS + REGWIN_SZ, %o0 ! pt_regs ptr ba,a,pt %xcc, rtrap +2: + sllx %g4, 63, %g4 ! _PAGE_VALID + or %g5, _PAGE_ACCESSED, %g5 + or %g5, %g4, %g5 + stxa %g5, [%g3 + %g1] ASI_PHYS_USE_EC ! store new PTE + stxa %g5, [%g0] ASI_DTLB_DATA_IN ! TLB load + retry + +3: + sllx %g4, 63, %g4 ! _PAGE_VALID + or %g5, _PAGE_ACCESSED, %g5 + or %g5, %g4, %g5 + stxa %g5, [%g3 + %g1] ASI_PHYS_USE_EC ! store new PTE + stxa %g5, [%g0] ASI_ITLB_DATA_IN ! TLB load + retry + /* Note check out head.h, this code isn't even used for UP, * for SMP things will be different. In particular the data * registers for cross calls will be: @@ -161,6 +189,7 @@ breakpoint_trap: .globl sys_pipe, sys_execve, sys_sigpause, sys_nis_syscall .globl sys_sigsuspend, sys_sigreturn + .globl sys32_execve, sys_ptrace sys_pipe: sethi %hi(sparc_pipe), %g1 @@ -180,6 +209,12 @@ sys_execve: jmpl %g1 + %lo(sparc_execve), %g0 add %sp, STACK_BIAS + REGWIN_SZ, %o0 +sys32_execve: + sethi %hi(sparc32_execve), %g1 + add %g1, %g4, %g1 + jmpl %g1 + %lo(sparc32_execve), %g0 + add %sp, STACK_BIAS + REGWIN_SZ, %o0 + sys_sigpause: /* NOTE: %o0 has a correct value already */ call do_sigpause @@ -199,7 +234,7 @@ sys_sigsuspend: ld [%curptr + AOFF_task_flags], %l5 andcc %l5, 0x20, %g0 - be,pt %icc, ret_sys_call + be,pt %icc, rtrap nop call syscall_trace nop @@ -211,13 +246,25 @@ sys_sigreturn: ld [%curptr + AOFF_task_flags], %l5 andcc %l5, 0x20, %g0 - be,pt %icc, ret_sys_call + be,pt %icc, rtrap nop call syscall_trace nop ba,a,pt %xcc, rtrap - /* This is how fork() was meant to be done, 11 instruction entry. -DaveM */ +sys_ptrace: + call do_ptrace + add %sp, STACK_BIAS + REGWIN_SZ, %o0 + + ld [%curptr + AOFF_task_flags], %l5 + andcc %l5, 0x20, %g0 + be,pt %icc, rtrap + nop + call syscall_trace + nop + ba,a,pt %xcc, rtrap + + /* This is how fork() was meant to be done, 10 instruction entry. -DaveM */ .globl sys_fork, sys_vfork, sys_clone sys_fork: sys_vfork: @@ -228,13 +275,12 @@ sys_clone: flushw rdpr %cwp, %o4 add %sp, STACK_BIAS + REGWIN_SZ, %o2 - brz,a %o1, 1f - mov %fp, %o1 -1: + movrz %o1, %fp, %o1 + /* Don't try this at home. */ stx %o4, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G0] call do_fork - add %l5, 8, %o7 + mov %l5, %o7 linux_sparc_ni_syscall: sethi %hi(sys_ni_syscall), %l7 @@ -281,6 +327,11 @@ linux_sparc_syscall: .globl syscall_is_too_hard syscall_is_too_hard: +#ifdef SYSCALL_TRACING /* Debugging... */ + mov %g1, %o0 ! o0=scall, o1=ptregs + call syscall_trace_entry + add %sp, STACK_BIAS + REGWIN_SZ, %o1 +#endif mov %i0, %o0 mov %i1, %o1 mov %i2, %o2 @@ -295,13 +346,12 @@ syscall_is_too_hard: call %l7 mov %i5, %o5 - stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0] -#if 0 - /* Debugging... */ - call syscall_trace_exit - add %sp, STACK_BIAS + REGWIN_SZ, %o0 - ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0], %o0 +#ifdef SYSCALL_TRACING /* Debugging... */ + call syscall_trace_exit ! o0=sysret, o1=ptregs + add %sp, STACK_BIAS + REGWIN_SZ, %o1 #endif + stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0] + .globl ret_sys_call ret_sys_call: ldx [%curptr + AOFF_task_flags], %l6 diff --git a/arch/sparc64/kernel/etrap.S b/arch/sparc64/kernel/etrap.S index f936b3071..0c166ec25 100644 --- a/arch/sparc64/kernel/etrap.S +++ b/arch/sparc64/kernel/etrap.S @@ -1,4 +1,4 @@ -/* $Id: etrap.S,v 1.17 1997/05/18 22:52:09 davem Exp $ +/* $Id: etrap.S,v 1.18 1997/05/19 05:58:51 davem Exp $ * etrap.S: Preparing for entry into the kernel on Sparc V9. * * Copyright (C) 1996, 1997 David S. Miller (davem@caip.rutgers.edu) @@ -29,59 +29,39 @@ etrap_irq: rdpr %tstate, %g1 sllx %g2, 20, %g2 or %g1, %g2, %g1 - - /* What happens more often? etrap when already in priv or from userland? */ andcc %g1, TSTATE_PRIV, %g0 bne,a,pn %xcc, 1f sub %sp, REGWIN_SZ + TRACEREG_SZ - STACK_BIAS, %g2 + rd %pic, %g3 - /* Just when going from userland to privileged mode, - * we have to change this stuff. - * - * Setup to run in NUCLEUS context, stash user context in - * secondary for later trap return. Note we must not change - * trap level until PRIMARY_CONTEXT is set to zero, else - * we fall out of NUCLEUS too soon and crash hard. - */ - mov PRIMARY_CONTEXT, %g1 - ldxa [%g1] ASI_DMMU, %g2 - stxa %g0, [%g1] ASI_DMMU - - mov SECONDARY_CONTEXT, %g1 - stxa %g2, [%g1] ASI_DMMU - - rd %pic, %g1 sethi %hi((PAGE_SIZE<<1)-TRACEREG_SZ-REGWIN_SZ), %g2 or %g2, %lo((PAGE_SIZE<<1)-TRACEREG_SZ-REGWIN_SZ), %g2 - add %g1, %g2, %g2 - rdpr %tstate, %g1 -1: - stx %g1, [%g2 + REGWIN_SZ + PT_V9_TSTATE] + add %g3, %g2, %g2 +1: stx %g1, [%g2 + REGWIN_SZ + PT_V9_TSTATE] rdpr %tpc, %g1 rdpr %tnpc, %g3 stx %g1, [%g2 + REGWIN_SZ + PT_V9_TPC] rd %y, %g1 + stx %g3, [%g2 + REGWIN_SZ + PT_V9_TNPC] stx %g1, [%g2 + REGWIN_SZ + PT_V9_Y] - - wrpr %g0, 0x0, %tl rdpr %pstate, %g1 save %g2, -STACK_BIAS, %sp - - /* Must guarentee that here andcc of TSTATE_PRIV at the top is - * still valid in %ccr register. Don't show this trick to your - * mom. -DaveM - */ bne,pn %xcc, 1f rdpr %canrestore, %g3 + rdpr %wstate, %g6 wrpr %g0, 0, %canrestore - wrpr %g3, 0, %otherwin - rdpr %wstate, %g6 sll %g6, 3, %g6 + wrpr %g3, 0, %otherwin wrpr %g6, %wstate - + sethi %uhi(KERNBASE), %g3 + sllx %g3, 32, %g3 + mov PRIMARY_CONTEXT, %g2 + stxa %g0, [%g2] ASI_DMMU + flush %g3 1: + wrpr %g0, 0x0, %tl mov %g1, %l1 mov %g4, %l4 mov %g5, %l5 @@ -89,6 +69,7 @@ etrap_irq: wrpr %l1, PSTATE_AG, %pstate stx %g1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G1] stx %g2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G2] + stx %g3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G3] stx %g4, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G4] stx %g5, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G5] @@ -97,19 +78,24 @@ etrap_irq: stx %i0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0] stx %i1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1] stx %i2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I2] + stx %i3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I3] stx %i4, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I4] stx %i5, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I5] stx %i6, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I6] stx %i7, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I7] wrpr %l1, (PSTATE_IE | PSTATE_AG), %pstate - srlx %sp, 43, %g4 + sethi %uhi(KERNBASE), %g4 rd %pic, %g6 + jmpl %l2 + 0x4, %g0 - sllx %g4, 43, %g4 + sllx %g4, 32, %g4 .globl etraptl1 etraptl1: rdpr %tstate, %g1 ba,pt %xcc, 1b sub %sp, REGWIN_SZ + TRACEREG_SZ - STACK_BIAS, %g2 + nop + nop + nop diff --git a/arch/sparc64/kernel/hack.S b/arch/sparc64/kernel/hack.S index 034bda2d0..6303bd9e9 100644 --- a/arch/sparc64/kernel/hack.S +++ b/arch/sparc64/kernel/hack.S @@ -10,28 +10,16 @@ breakpoint: retl;nop do_cee: retl;nop .globl do_cee_tl1 do_cee_tl1: retl;nop - .globl do_dae -do_dae: retl;nop .globl do_dae_tl1 do_dae_tl1: retl;nop - .globl do_div0 -do_div0: retl;nop .globl do_div0_tl1 do_div0_tl1: retl;nop - .globl do_fpdis -do_fpdis: retl;nop .globl do_fpdis_tl1 do_fpdis_tl1: retl;nop - .globl do_fpieee -do_fpieee: retl;nop .globl do_fpieee_tl1 do_fpieee_tl1: retl;nop - .globl do_fpother -do_fpother: retl;nop .globl do_fpother_tl1 do_fpother_tl1: retl;nop - .globl do_iae -do_iae: retl;nop .globl do_iae_tl1 do_iae_tl1: retl;nop .globl do_ill_tl1 @@ -50,16 +38,10 @@ do_mna_tl1: retl;nop do_paw: retl;nop .globl do_paw_tl1 do_paw_tl1: retl;nop - .globl do_privact -do_privact: retl;nop - .globl do_privop -do_privop: retl;nop .globl do_stdfmna do_stdfmna: retl;nop .globl do_stdfmna_tl1 do_stdfmna_tl1: retl;nop - .globl do_tof -do_tof: retl;nop .globl do_tof_tl1 do_tof_tl1: retl;nop .globl do_vaw @@ -190,9 +172,3 @@ sunos_wait4: retl;nop sunos_write: retl;nop .globl sunos_writev sunos_writev: retl;nop - .globl sys_ptrace -sys_ptrace: retl;nop - .globl syscall_trace -syscall_trace: retl;nop - .globl sys32_ptrace -sys32_ptrace: retl;nop diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index bc9a8053e..3c9b1a89e 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.12 1997/04/16 05:56:20 davem Exp $ +/* $Id: irq.c,v 1.13 1997/05/27 07:54:28 davem Exp $ * irq.c: UltraSparc IRQ handling/init/registry. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -382,15 +382,15 @@ void free_irq(unsigned int irq, void *dev_cookie) /* Per-processor IRQ locking depth, both SMP and non-SMP code use this. */ unsigned int local_irq_count[NR_CPUS]; -atomic_t __sparc64_bh_counter = ATOMIC_INIT(0); -#ifdef __SMP__ -#error SMP not supported on sparc64 just yet -#else +#ifndef __SMP__ +int __sparc64_bh_counter = 0; #define irq_enter(cpu, irq) (local_irq_count[cpu]++) #define irq_exit(cpu, irq) (local_irq_count[cpu]--) +#else +#error SMP not supported on sparc64 just yet #endif /* __SMP__ */ void report_spurious_ivec(struct pt_regs *regs) diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index 4e2bbe016..593c1efc6 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.11 1997/05/18 22:52:19 davem Exp $ +/* $Id: process.c,v 1.12 1997/05/23 09:35:43 jj Exp $ * arch/sparc64/kernel/process.c * * Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu) @@ -355,6 +355,7 @@ void flush_thread(void) get_mmu_context(current); } current->tss.current_ds = USER_DS; + spitfire_set_secondary_context (current->mm->context); } static __inline__ void copy_regs(struct pt_regs *dst, struct pt_regs *src) diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S index 1c4c4df04..0f1dceb33 100644 --- a/arch/sparc64/kernel/rtrap.S +++ b/arch/sparc64/kernel/rtrap.S @@ -1,4 +1,4 @@ -/* $Id: rtrap.S,v 1.14 1997/05/18 08:42:14 davem Exp $ +/* $Id: rtrap.S,v 1.18 1997/05/27 06:28:05 davem Exp $ * rtrap.S: Preparing for return from trap on Sparc V9. * * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -9,11 +9,14 @@ #include <asm/pstate.h> #include <asm/ptrace.h> #include <asm/spitfire.h> +#include <asm/head.h> -/* We assume here this is entered with AG, MG and IG bits in pstate clear */ + /* We assume here that this is entered with AG, MG and IG bits + * in pstate clear. + */ .text - .align 4 + .align 32 .globl rtrap rtrap: sethi %hi(bh_active), %l2 @@ -23,24 +26,26 @@ rtrap: ldx [%l2 + %g4], %l3 ldx [%l1 + %g4], %l4 andcc %l3, %l4, %g0 + nop + be,pt %xcc, 2f nop call do_bottom_half nop -2: - ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TSTATE], %l1 - ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TPC], %l2 +2: ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TSTATE], %l1 sethi %hi(0xf << 20), %l4 andcc %l1, TSTATE_PRIV, %l3 and %l1, %l4, %l4 + rdpr %pstate, %l7 - andn %l1, %l4, %l1 /* XXX May not be needed -DaveM */ + andn %l1, %l4, %l1 be,pt %icc, to_user andn %l7, PSTATE_IE, %l7 -3: +3: ldx [%g6 + AOFF_task_tss + AOFF_thread_ctx], %l6 ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G1], %g1 ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G2], %g2 ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G3], %g3 + ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G4], %g4 ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G5], %g5 ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G6], %g6 @@ -49,54 +54,54 @@ rtrap: ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1], %i1 ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I2], %i2 ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I3], %i3 + ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I4], %i4 ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I5], %i5 ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I6], %i6 ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I7], %i7 ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_Y], %o3 + ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TPC], %l2 ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC], %o2 - rdpr %tl, %o4 wr %o3, %g0, %y - add %o4, 1, %o4 srl %l4, 20, %l4 wrpr %l7, %g0, %pstate wrpr %l4, 0x0, %pil - wrpr %o4, %g0, %tl + wrpr %g0, 0x1, %tl wrpr %l1, %g0, %tstate wrpr %l2, %g0, %tpc brnz,pn %l3, 1f wrpr %o2, %g0, %tnpc - /* We came here from to_user, ie. we have now AG. - * Also have to push user context back into primary. - */ - mov SECONDARY_CONTEXT, %g6 - mov PRIMARY_CONTEXT, %g7 - ldxa [%g6] ASI_DMMU, %g4 - stxa %g4, [%g7] ASI_DMMU - membar #Sync /* XXX flushi would be better -DaveM */ + mov PRIMARY_CONTEXT, %l7 + sethi %uhi(KERNBASE), %l5 + sllx %l5, 32, %l5 + stxa %l6, [%l7] ASI_DMMU + flush %l5 + rdpr %wstate, %l1 + rdpr %otherwin, %l2 + srl %l1, 3, %l1 - rdpr %wstate, %g1 - rdpr %otherwin, %g2 - srl %g1, 3, %g1 - wrpr %g2, %g0, %canrestore - wrpr %g1, %g0, %wstate + wrpr %l2, %g0, %canrestore + wrpr %l1, %g0, %wstate wrpr %g0, %g0, %otherwin -1: - restore +1: restore retry to_user: sethi %hi(need_resched), %l0 or %l0, %lo(need_resched), %l0 ld [%l0 + %g4], %l0 + wrpr %l7, PSTATE_IE, %pstate - brz,pt %l0, 1f + brz,pt %l0, check_signal ldx [%g6 + AOFF_task_signal], %l0 call schedule nop -1: + ldx [%g6 + AOFF_task_signal], %l0 + nop +check_signal: ldx [%g6 + AOFF_task_blocked], %o0 + or %l7, PSTATE_AG, %l7 ! Will need this for setting back wstate andncc %l0, %o0, %g0 be,pt %xcc, check_user_wins @@ -105,8 +110,17 @@ to_user: call do_signal add %sp, STACK_BIAS + REGWIN_SZ, %o1 check_user_wins: +#if 0 + call user_rtrap_report + add %sp, STACK_BIAS + REGWIN_SZ, %o0 +#endif ldx [%g6 + AOFF_task_tss + AOFF_thread_w_saved], %o2 + brz,pt %o2, 3b add %sp, STACK_BIAS + REGWIN_SZ, %o1 call fault_in_user_windows add %o7, 3b-.-4, %o7 + nop + nop + nop + nop diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index 47d900977..832d3b97f 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.6 1997/05/04 07:21:04 davem Exp $ +/* $Id: setup.c,v 1.7 1997/05/20 07:58:56 jj Exp $ * linux/arch/sparc64/kernel/setup.c * * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu) @@ -25,6 +25,7 @@ #include <linux/string.h> #include <linux/blk.h> #include <linux/init.h> +#include <linux/inet.h> #include <asm/segment.h> #include <asm/system.h> @@ -247,6 +248,10 @@ extern void register_console(void (*proc)(const char *)); char saved_command_line[256]; char reboot_command[256]; +#ifdef CONFIG_ROOT_NFS +extern char nfs_root_addrs[]; +#endif + unsigned long phys_base; static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 }; @@ -346,6 +351,31 @@ __initfunc(void setup_arch(char **cmdline_p, init_task.mm->context = (unsigned long) NO_CONTEXT; init_task.tss.kregs = &fake_swapper_regs; +#ifdef CONFIG_ROOT_NFS + if (!*nfs_root_addrs) { + int chosen = prom_finddevice ("/chosen"); + u32 cl, sv, gw; + char *p = nfs_root_addrs; + + cl = prom_getintdefault (chosen, "client-ip", 0); + sv = prom_getintdefault (chosen, "server-ip", 0); + gw = prom_getintdefault (chosen, "gateway-ip", 0); + if (cl && sv) { + strcpy (p, in_ntoa (cl)); + p += strlen (p); + *p++ = ':'; + strcpy (p, in_ntoa (sv)); + p += strlen (p); + *p++ = ':'; + if (gw) { + strcpy (p, in_ntoa (gw)); + p += strlen (p); + } + strcpy (p, "::::none"); + } + } +#endif + #ifdef CONFIG_SUN_SERIAL *memory_start_p = sun_serial_setup(*memory_start_p); /* set this up ASAP */ #endif diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index 1a595491a..f81e30093 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c @@ -1,4 +1,4 @@ -/* $Id: signal.c,v 1.2 1997/05/18 08:42:15 davem Exp $ +/* $Id: signal.c,v 1.4 1997/05/27 06:28:05 davem Exp $ * arch/sparc64/kernel/signal.c * * Copyright (C) 1991, 1992 Linus Torvalds @@ -61,7 +61,7 @@ struct new_signal_frame { */ asmlinkage void _sigpause_common(unsigned int set, struct pt_regs *regs) { - unsigned int mask; + unsigned long mask; #ifdef CONFIG_SPARC32_COMPAT if (current->tss.flags & SPARC_FLAG_32BIT) { @@ -134,7 +134,7 @@ void do_sigreturn(struct pt_regs *regs) struct new_signal_frame *sf; unsigned long tpc, tnpc, tstate; __siginfo_fpu_t *fpu_save; - int mask; + unsigned long mask; #ifdef CONFIG_SPARC32_COMPAT if (current->tss.flags & SPARC_FLAG_32BIT) { @@ -270,8 +270,15 @@ new_setup_frame(struct sigaction *sa, struct pt_regs *regs, regs->tnpc = (regs->tpc + 4); /* Flush instruction space. */ - __asm__ __volatile__ ("flush %0; flush %0 + 4" : : "r" (&(sf->insns[0]))); - + __asm__ __volatile__(" + membar #StoreStore + stxa %%g0, [%0] %2 + stxa %%g0, [%1] %2 + flush %%g4 + " : /* no outputs */ + : "r" (((unsigned long)&(sf->insns[0])) & ~(PAGE_MASK)), + "r" ((((unsigned long)&(sf->insns[0])) & ~(PAGE_MASK)) + PAGE_SIZE), + "i" (ASI_IC_TAG)); } static inline void handle_signal(unsigned long signr, struct sigaction *sa, @@ -323,7 +330,7 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs, #endif while ((signr = current->signal & mask) != 0) { signr = ffz(~signr); - clear_bit(signr, ¤t->signal); + clear_bit(signr + 32, ¤t->signal); sa = current->sig->action + signr; signr++; if ((current->flags & PF_PTRACED) && signr != SIGKILL) { diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index d8e61511d..33892065f 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c @@ -1,4 +1,4 @@ -/* $Id: signal32.c,v 1.8 1997/05/18 08:42:15 davem Exp $ +/* $Id: signal32.c,v 1.10 1997/05/27 06:28:07 davem Exp $ * arch/sparc64/kernel/signal32.c * * Copyright (C) 1991, 1992 Linus Torvalds @@ -398,8 +398,15 @@ new_setup_frame32(struct sigaction *sa, struct pt_regs *regs, regs->tnpc = (regs->tpc + 4); /* Flush instruction space. */ - __asm__ __volatile__ ("flush %0; flush %0 + 4" : : "r" (&(sf->insns[0]))); - + __asm__ __volatile__(" + membar #StoreStore + stxa %%g0, [%0] %2 + stxa %%g0, [%1] %2 + flush %%g4 + " : /* no outputs */ + : "r" (((unsigned long)&(sf->insns[0])) & ~(PAGE_MASK)), + "r" ((((unsigned long)&(sf->insns[0])) & ~(PAGE_MASK)) + PAGE_SIZE), + "i" (ASI_IC_TAG)); } /* Setup a Solaris stack frame */ @@ -677,7 +684,7 @@ asmlinkage int do_signal32(unsigned long oldmask, struct pt_regs * regs, while ((signr = current->signal & mask) != 0) { signr = ffz(~signr); - clear_bit(signr, ¤t->signal); + clear_bit(signr + 32, ¤t->signal); sa = current->sig->action + signr; signr++; if ((current->flags & PF_PTRACED) && signr != SIGKILL) { diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index 147b60c34..c54036de6 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c @@ -1,4 +1,4 @@ -/* $Id: sys_sparc32.c,v 1.13 1997/05/18 04:16:44 davem Exp $ +/* $Id: sys_sparc32.c,v 1.18 1997/05/27 06:28:08 davem Exp $ * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. * * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -48,7 +48,6 @@ extern asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, extern asmlinkage int sys_bdflush(int func, long data); extern asmlinkage int sys_uselib(const char * library); extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg); -extern asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); extern asmlinkage int sys_mknod(const char * filename, int mode, dev_t dev); extern asmlinkage int sys_mkdir(const char * pathname, int mode); extern asmlinkage int sys_rmdir(const char * pathname); @@ -147,6 +146,69 @@ extern asmlinkage int sys_socket(int family, int type, int protocol); extern asmlinkage int sys_socketpair(int family, int type, int protocol, int usockvec[2]); extern asmlinkage int sys_shutdown(int fd, int how); +/* + * In order to reduce some races, while at the same time doing additional + * checking and hopefully speeding things up, we copy filenames to the + * kernel data space before using them.. + * + * POSIX.1 2.4: an empty pathname is invalid (ENOENT). + */ +static inline int do_getname32(u32 filename, char *page) +{ + int retval; + + /* 32bit pointer will be always far below TASK_SIZE :)) */ + retval = strncpy_from_user((char *)page, (char *)A(filename), PAGE_SIZE); + if (retval > 0) { + if (retval < PAGE_SIZE) + return 0; + return -ENAMETOOLONG; + } else if (!retval) + retval = -ENOENT; + return retval; +} + +/* + * This is a single page for faster getname. + * If the page is available when entering getname, use it. + * If the page is not available, call __get_free_page instead. + * This works even though do_getname can block (think about it). + * -- Michael Chastain, based on idea of Linus Torvalds, 1 Dec 1996. + * We don't use the common getname/putname from namei.c, so that + * this still works well, as every routine which calls getname32 + * will then call getname, then putname and then putname32. + */ +static unsigned long name_page_cache32 = 0; + +void putname32(char * name) +{ + if (name_page_cache32 == 0) + name_page_cache32 = (unsigned long) name; + else + free_page((unsigned long) name); +} + +int getname32(u32 filename, char **result) +{ + unsigned long page; + int retval; + + page = name_page_cache32; + name_page_cache32 = 0; + if (!page) { + page = __get_free_page(GFP_KERNEL); + if (!page) + return -ENOMEM; + } + + retval = do_getname32(filename, (char *) page); + if (retval < 0) + putname32( (char *) page ); + else + *result = (char *) page; + return retval; +} + asmlinkage int sys32_ioperm(u32 from, u32 num, int on) { return sys_ioperm((unsigned long)from, (unsigned long)num, on); @@ -558,13 +620,6 @@ asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, u32 arg) } } -/* Conversion of args should be probably done in all the locations where it is handled, - using if (current->tss.flags & SPARC_FLAG_32BIT */ -asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, u32 arg) -{ - return sys_ioctl(fd, cmd, (unsigned long)arg); -} - asmlinkage int sys32_mknod(u32 filename, int mode, __kernel_dev_t32 dev) { return sys_mknod((const char *)A(filename), mode, dev); @@ -704,14 +759,21 @@ asmlinkage int sys32_utime(u32 filename, u32 times) struct utimbuf t; unsigned long old_fs; int ret; + char *filenam; + if (!times) + return sys_utime((char *)A(filename), NULL); if (get_user (t.actime, &(((struct utimbuf32 *)A(times))->actime)) || __get_user (t.modtime, &(((struct utimbuf32 *)A(times))->modtime))) return -EFAULT; - old_fs = get_fs(); - set_fs (KERNEL_DS); - ret = sys_utime((char *)A(filename), &t); - set_fs (old_fs); + ret = getname32 (filename, &filenam); + if (!ret) { + old_fs = get_fs(); + set_fs (KERNEL_DS); + ret = sys_utime(filenam, &t); + set_fs (old_fs); + putname32 (filenam); + } return ret; } @@ -992,6 +1054,7 @@ out: asmlinkage int sys32_select(int n, u32 inp, u32 outp, u32 exp, u32 tvp) { + struct timeval kern_tv, *ktvp; unsigned long old_fs; char *p; u32 *q; @@ -1015,9 +1078,15 @@ asmlinkage int sys32_select(int n, u32 inp, u32 outp, u32 exp, u32 tvp) __get_user (q[PAGE_SIZE/2], Exp+1)) goto out; } + ktvp = NULL; + if(tvp) { + if(copy_from_user(&kern_tv, (struct timeval *)A(tvp), sizeof(*ktvp))) + goto out; + ktvp = &kern_tv; + } old_fs = get_fs (); set_fs (KERNEL_DS); - ret = sys_select(n, (fd_set *)p, (fd_set *)(p + PAGE_SIZE/4), (fd_set *)(p + PAGE_SIZE/2), (struct timeval *)A(tvp)); + ret = sys_select(n, (fd_set *)p, (fd_set *)(p + PAGE_SIZE/4), (fd_set *)(p + PAGE_SIZE/2), ktvp); set_fs (old_fs); q = (u32 *)p; Inp = (u32 *)A(inp); Outp = (u32 *)A(outp); Exp = (u32 *)A(exp); @@ -1065,12 +1134,17 @@ asmlinkage int sys32_newstat(u32 filename, u32 statbuf) { int ret; struct stat s; + char *filenam; unsigned long old_fs = get_fs(); - set_fs (KERNEL_DS); - ret = sys_newstat((char *)A(filename), &s); - set_fs (old_fs); - if (putstat (statbuf, &s)) return -EFAULT; + ret = getname32 (filename, &filenam); + if (!ret) { + set_fs (KERNEL_DS); + ret = sys_newstat(filenam, &s); + set_fs (old_fs); + putname32 (filenam); + if (putstat (statbuf, &s)) return -EFAULT; + } return ret; } @@ -1078,12 +1152,17 @@ asmlinkage int sys32_newlstat(u32 filename, u32 statbuf) { int ret; struct stat s; + char *filenam; unsigned long old_fs = get_fs(); - set_fs (KERNEL_DS); - ret = sys_newlstat((char *)A(filename), &s); - set_fs (old_fs); - if (putstat (statbuf, &s)) return -EFAULT; + ret = getname32 (filename, &filenam); + if (!ret) { + set_fs (KERNEL_DS); + ret = sys_newlstat(filenam, &s); + set_fs (old_fs); + putname32 (filenam); + if (putstat (statbuf, &s)) return -EFAULT; + } return ret; } @@ -1987,6 +2066,144 @@ asmlinkage int sys32_nfsservctl(int cmd, u32 argp, u32 resp) return sys_nfsservctl(cmd, (void *)A(argp), (void *)A(resp)); } +/* + * count32() counts the number of arguments/envelopes + */ +static int count32(u32 * argv) +{ + int i = 0; + + if (argv != NULL) { + for (;;) { + u32 p; int error; + + error = get_user(p,argv); + if (error) return error; + if (!p) break; + argv++; i++; + } + } + return i; +} + +/* + * 'copy_string32()' copies argument/envelope strings from user + * memory to free pages in kernel mem. These are in a format ready + * to be put directly into the top of new user memory. + */ +static unsigned long +copy_strings32(int argc,u32 * argv,unsigned long *page, + unsigned long p) +{ + u32 str; + + if (!p) return 0; /* bullet-proofing */ + while (argc-- > 0) { + int len; + unsigned long pos; + + get_user(str, argv+argc); + if (!str) panic("VFS: argc is wrong"); + len = strlen_user((char *)A(str)); /* includes the '\0' */ + if (p < len) /* this shouldn't happen - 128kB */ + return 0; + p -= len; pos = p; + while (len) { + char *pag; + int offset, bytes_to_copy; + + offset = pos % PAGE_SIZE; + if (!(pag = (char *) page[pos/PAGE_SIZE]) && + !(pag = (char *) page[pos/PAGE_SIZE] = + (unsigned long *) get_free_page(GFP_USER))) + return 0; + bytes_to_copy = PAGE_SIZE - offset; + if (bytes_to_copy > len) + bytes_to_copy = len; + copy_from_user(pag + offset, (char *)A(str), bytes_to_copy); + pos += bytes_to_copy; + str += bytes_to_copy; + len -= bytes_to_copy; + } + } + return p; +} + +/* + * sys32_execve() executes a new program. + */ +static inline int +do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs) +{ + struct linux_binprm bprm; + int retval; + int i; + + bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *); + for (i=0 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */ + bprm.page[i] = 0; + retval = open_namei(filename, 0, 0, &bprm.inode, NULL); + if (retval) + return retval; + bprm.filename = filename; + bprm.sh_bang = 0; + bprm.java = 0; + bprm.loader = 0; + bprm.exec = 0; + bprm.dont_iput = 0; + if ((bprm.argc = count32(argv)) < 0) + return bprm.argc; + if ((bprm.envc = count32(envp)) < 0) + return bprm.envc; + + retval = prepare_binprm(&bprm); + + if(retval>=0) { + bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p, 2); + bprm.exec = bprm.p; + bprm.p = copy_strings32(bprm.envc,envp,bprm.page,bprm.p); + bprm.p = copy_strings32(bprm.argc,argv,bprm.page,bprm.p); + if (!bprm.p) + retval = -E2BIG; + } + + if(retval>=0) + retval = search_binary_handler(&bprm,regs); + if(retval>=0) + /* execve success */ + return retval; + + /* Something went wrong, return the inode and free the argument pages*/ + if(!bprm.dont_iput) + iput(bprm.inode); + for (i=0 ; i<MAX_ARG_PAGES ; i++) + free_page(bprm.page[i]); + return(retval); +} + +/* + * sparc32_execve() executes a new program after the asm stub has set + * things up for us. This should basically do what I want it to. + */ +asmlinkage int sparc32_execve(struct pt_regs *regs) +{ + int error, base = 0; + char *filename; + + /* Check for indirect call. */ + if((u32)regs->u_regs[UREG_G1] == 0) + base = 1; + + error = getname((char *)(unsigned long)(u32)regs->u_regs[base + UREG_I0], &filename); + if(error) + return error; + error = do_execve32(filename, + (u32 *)A((u32)regs->u_regs[base + UREG_I1]), + (u32 *)A((u32)regs->u_regs[base + UREG_I2]), regs); + putname(filename); + return error; +} + struct ncp_mount_data32 { int version; unsigned int ncp_fd; diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index 8ff04f02a..02707186a 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S @@ -1,4 +1,4 @@ -/* $Id: systbls.S,v 1.8 1997/04/21 08:34:23 jj Exp $ +/* $Id: systbls.S,v 1.11 1997/05/27 19:30:20 jj Exp $ * systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * @@ -22,13 +22,13 @@ sys_call_table32: /*10*/ .xword sys32_unlink, sunos_execv, sys32_chdir, sys_nis_syscall, sys32_mknod /*15*/ .xword sys32_chmod, sys32_chown, sparc32_brk, sys_nis_syscall, sys32_lseek /*20*/ .xword sys_getpid, sys_nis_syscall, sys_nis_syscall, sys_setuid, sys_getuid -/*25*/ .xword sys32_time, sys32_ptrace, sys_alarm, sys_nis_syscall, sys_pause +/*25*/ .xword sys32_time, sys_ptrace, sys_alarm, sys_nis_syscall, sys_pause /*30*/ .xword sys32_utime, sys_stty, sys_gtty, sys32_access, sys_nice .xword sys_ftime, sys_sync, sys_kill, sys32_newstat, sys_nis_syscall /*40*/ .xword sys32_newlstat, sys_dup, sys_pipe, sys32_times, sys_profil .xword sys_nis_syscall, sys_setgid, sys_getgid, sys32_signal, sys_geteuid /*50*/ .xword sys_getegid, sys32_acct, sys_nis_syscall, sys_nis_syscall, sys32_ioctl - .xword sys32_reboot, sys_nis_syscall, sys32_symlink, sys32_readlink, sys_execve + .xword sys32_reboot, sys_nis_syscall, sys32_symlink, sys32_readlink, sys32_execve /*60*/ .xword sys_umask, sys32_chroot, sys32_newfstat, sys_nis_syscall, sys_getpagesize .xword sys_nis_syscall, sys_vfork, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall /*70*/ .xword sys_nis_syscall, sys32_mmap, sys_nis_syscall, sys32_munmap, sys32_mprotect @@ -61,7 +61,7 @@ sys_call_table32: .xword sys_nis_syscall, sys32_socketcall, sys32_syslog, sys32_olduname, sys_nis_syscall /*210*/ .xword sys_idle, sys_nis_syscall, sys32_waitpid, sys32_swapoff, sys32_sysinfo .xword sys32_ipc, sys_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex -/*220*/ .xword sys_sigprocmask, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getpgid +/*220*/ .xword sys32_sigprocmask, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getpgid .xword sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys_setfsuid, sys_setfsgid /*230*/ .xword sys32_llseek, sys32_time, sys_nis_syscall, sys_stime, sys_nis_syscall .xword sys_nis_syscall, sys32_llseek, sys32_mlock, sys32_munlock, sys_mlockall @@ -153,7 +153,7 @@ sunos_sys_table: /*50*/ .xword sunos_nosys, sys_acct, sunos_nosys .xword sunos_mctl, sunos_ioctl, sys_reboot .xword sunos_nosys, sys_symlink, sys_readlink - .xword sys_execve, sys_umask, sys_chroot + .xword sys32_execve, sys_umask, sys_chroot .xword sys_newfstat, sunos_nosys, sys_getpagesize .xword sys_msync, sys_vfork, sunos_nosys .xword sunos_nosys, sunos_sbrk, sunos_sstk diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index c9774df06..6f96408ad 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c @@ -1,4 +1,4 @@ -/* $Id: traps.c,v 1.10 1997/05/18 08:42:16 davem Exp $ +/* $Id: traps.c,v 1.13 1997/05/27 19:30:08 jj Exp $ * arch/sparc/kernel/traps.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -24,76 +24,271 @@ #include <asm/unistd.h> #include <asm/uaccess.h> -/* #define TRAP_DEBUG */ +/* #define SYSCALL_TRACING */ +/* #define VERBOSE_SYSCALL_TRACING */ -struct trap_trace_entry { - unsigned long pc; - unsigned long type; +#ifdef SYSCALL_TRACING +#ifdef VERBOSE_SYSCALL_TRACING +struct sdesc { + int scall_num; + char *name; + int num_args; + char arg_is_string[6]; +} sdesc_entries[] = { + { 0, "setup", 0, }, + { 1, "exit", 1, { 0, } }, + { 2, "fork", 0, }, + { 3, "read", 3, { 0, 0, 0, } }, + { 4, "write", 3, { 0, 0, 0, } }, + { 5, "open", 3, { 1, 0, 0, } }, + { 6, "close", 1, { 0, } }, + { 7, "wait4", 4, { 0, 0, 0, 0, } }, + { 8, "creat", 2, { 1, 0, } }, + { 9, "link", 2, { 1, 1, } }, + { 10, "unlink", 1, { 1, } }, + { 11, "execv", 2, { 1, 0, } }, + { 12, "chdir", 1, { 1, } }, + { 15, "chmod", 2, { 1, 0, } }, + { 16, "chown", 3, { 1, 0, 0, } }, + { 17, "brk", 1, { 0, } }, + { 19, "lseek", 3, { 0, 0, 0, } }, + { 27, "alarm", 1, { 0, } }, + { 29, "pause", 0, }, + { 33, "access", 2, { 1, 0, } }, + { 36, "sync", 0, }, + { 37, "kill", 2, { 0, 0, } }, + { 38, "stat", 2, { 1, 0, } }, + { 40, "lstat", 2, { 1, 0, } }, + { 41, "dup", 1, { 0, } }, + { 42, "pipd", 0, }, + { 54, "ioctl", 3, { 0, 0, 0, } }, + { 57, "symlink", 2, { 1, 1, } }, + { 58, "readlink", 3, { 1, 0, 0, } }, + { 59, "execve", 3, { 1, 0, 0, } }, + { 60, "umask", 1, { 0, } }, + { 62, "fstat", 2, { 0, 0, } }, + { 64, "getpagesize", 0, }, + { 71, "mmap", 6, { 0, 0, 0, 0, 0, 0, } }, + { 73, "munmap", 2, { 0, 0, } }, + { 74, "mprotect", 3, { 0, 0, 0, } }, + { 83, "setitimer", 3, { 0, 0, 0, } }, + { 90, "dup2", 2, { 0, 0, } }, + { 92, "fcntl", 3, { 0, 0, 0, } }, + { 93, "select", 5, { 0, 0, 0, 0, 0, } }, + { 97, "socket", 3, { 0, 0, 0, } }, + { 98, "connect", 3, { 0, 0, 0, } }, + { 99, "accept", 3, { 0, 0, 0, } }, + { 101, "send", 4, { 0, 0, 0, 0, } }, + { 102, "recv", 4, { 0, 0, 0, 0, } }, + { 104, "bind", 3, { 0, 0, 0, } }, + { 105, "setsockopt", 5, { 0, 0, 0, 0, 0, } }, + { 106, "listen", 2, { 0, 0, } }, + { 120, "readv", 3, { 0, 0, 0, } }, + { 121, "writev", 3, { 0, 0, 0, } }, + { 123, "fchown", 3, { 0, 0, 0, } }, + { 124, "fchmod", 2, { 0, 0, } }, + { 128, "rename", 2, { 1, 1, } }, + { 129, "truncate", 2, { 1, 0, } }, + { 130, "ftruncate", 2, { 0, 0, } }, + { 131, "flock", 2, { 0, 0, } }, + { 136, "mkdir", 2, { 1, 0, } }, + { 137, "rmdir", 1, { 1, } }, + { 146, "killpg", 1, { 0, } }, + { 157, "statfs", 2, { 1, 0, } }, + { 158, "fstatfs", 2, { 0, 0, } }, + { 159, "umount", 1, { 1, } }, + { 167, "mount", 5, { 1, 1, 1, 0, 0, } }, + { 174, "getdents", 3, { 0, 0, 0, } }, + { 176, "fchdir", 2, { 0, 0, } }, + { 198, "sigaction", 3, { 0, 0, 0, } }, + { 201, "sigsuspend", 1, { 0, } }, + { 206, "socketcall", 2, { 0, 0, } }, + { 216, "sigreturn", 0, }, + { 230, "newselect", 5, { 0, 0, 0, 0, 0, } }, + { 236, "llseek", 5, { 0, 0, 0, 0, 0, } }, + { 251, "sysctl", 1, { 0, } }, }; +#define NUM_SDESC_ENTRIES (sizeof(sdesc_entries) / sizeof(sdesc_entries[0])) +#endif -int trap_curbuf = 0; -struct trap_trace_entry trapbuf[1024]; +#ifdef VERBOSE_SYSCALL_TRACING +static char scall_strbuf[512]; +#endif -void syscall_trace_entry(struct pt_regs *regs) +void syscall_trace_entry(unsigned long g1, struct pt_regs *regs) { - printk("%s[%d]: ", current->comm, current->pid); - printk("scall<%ld> (could be %ld)\n", (long) regs->u_regs[UREG_G1], - (long) regs->u_regs[UREG_I0]); -} +#ifdef VERBOSE_SYSCALL_TRACING + struct sdesc *sdp; + int i; +#endif -void syscall_trace_exit(struct pt_regs *regs) -{ - printk("Syscall return check, reg dump.\n"); - show_regs(regs); + printk("SYS[%s:%d]: <%d> ", current->comm, current->pid, (int)g1); +#ifdef VERBOSE_SYSCALL_TRACING + sdp = NULL; + for(i = 0; i < NUM_SDESC_ENTRIES; i++) + if(sdesc_entries[i].scall_num == g1) { + sdp = &sdesc_entries[i]; + break; + } + if(sdp) { + printk("%s(", sdp->name); + for(i = 0; i < sdp->num_args; i++) { + if(i) + printk(","); + if(!sdp->arg_is_string[i]) + printk("%08x", (unsigned int)regs->u_regs[UREG_I0 + i]); + else { + strncpy_from_user(scall_strbuf, + (char *)regs->u_regs[UREG_I0 + i], + 512); + printk("%s", scall_strbuf); + } + } + printk(") "); + } +#endif } -void sparc64_dtlb_fault_handler (void) +unsigned long syscall_trace_exit(unsigned long retval, struct pt_regs *regs) { - printk ("sparc64_dtlb_fault_handler\n"); - while (1); - /* Die for now... */ + printk("ret[%08x]\n", (unsigned int) retval); + return retval; } +#endif /* SYSCALL_TRACING */ -void sparc64_dtlb_refbit_handler (struct pt_regs *regs) +#if 0 +void user_rtrap_report(struct pt_regs *regs) { - printk ("sparc64_dtlb_refbit_handler[%016lx]\n", regs->tpc); - while (1); - /* Die for now... */ -} + static int hits = 0; -void sparc64_itlb_refbit_handler (void) -{ - printk ("sparc64_itlb_refbit_handler\n"); - while (1); - /* Die for now... */ + /* Bwahhhhrggg... */ + if(regs->tpc == 0x1f294UL && ++hits == 2) { + register unsigned long ctx asm("o4"); + register unsigned long paddr asm("o5"); + unsigned long cwp, wstate; + + printk("RT[%016lx:%016lx] ", regs->tpc, regs->u_regs[UREG_I6]); + __asm__ __volatile__("rdpr %%cwp, %0" : "=r" (cwp)); + __asm__ __volatile__("rdpr %%wstate, %0" : "=r" (wstate)); + printk("CWP[%d] WSTATE[%016lx]\n" + "TSS( ksp[%016lx] kpc[%016lx] wstate[%016lx] w_saved[%d] flgs[%x]" + " cur_ds[%d] )\n", cwp, wstate, + current->tss.ksp, current->tss.kpc, current->tss.wstate, + (int) current->tss.w_saved, current->tss.flags, + current->tss.current_ds); + __asm__ __volatile__(" + rdpr %%pstate, %%o3 + wrpr %%o3, %2, %%pstate + mov %%g7, %%o5 + mov 0x10, %%o4 + ldxa [%%o4] %3, %%o4 + wrpr %%o3, 0x0, %%pstate + " : "=r" (ctx), "=r" (paddr) + : "i" (PSTATE_MG|PSTATE_IE), "i" (ASI_DMMU)); + + printk("MMU[ppgd(%016lx)sctx(%d)] ", paddr, ctx); + printk("mm->context(%016lx) mm->pgd(%p)\n", + current->mm->context, current->mm->pgd); + printk("TASK: signal[%016lx] blocked[%016lx]\n", + current->signal, current->blocked); + show_regs(regs); + while(1) + barrier(); + } } +#endif void bad_trap (struct pt_regs *regs, long lvl) { - printk ("Bad trap %d (tstate %016lx tpc %016lx tnpc %016lx)\n", lvl, regs->tstate, regs->tpc, regs->tnpc); - while (1); - /* Die for now... */ + lock_kernel (); + if (lvl < 0x100) { + char buffer[24]; + + sprintf (buffer, "Bad hw trap %lx at tl0\n", lvl); + die_if_kernel (buffer, regs); + } + if (regs->tstate & TSTATE_PRIV) + die_if_kernel ("Kernel bad trap", regs); + current->tss.sig_desc = SUBSIG_BADTRAP(lvl - 0x100); + current->tss.sig_address = regs->tpc; + send_sig(SIGILL, current, 1); + unlock_kernel (); } void bad_trap_tl1 (struct pt_regs *regs, long lvl) { - printk ("Bad trap %d at tl1+ (tstate %016lx tpc %016lx tnpc %016lx)\n", lvl, regs->tstate, regs->tpc, regs->tnpc); - while (1); - /* Die for now... */ + char buffer[24]; + + lock_kernel (); + sprintf (buffer, "Bad trap %lx at tl>0", lvl); + die_if_kernel (buffer, regs); } void data_access_exception (struct pt_regs *regs) { - printk ("Unhandled data access exception sfsr %016lx sfar %016lx\n", spitfire_get_dsfsr(), spitfire_get_sfar()); + lock_kernel (); + printk ("Unhandled data access exception "); + printk("sfsr %016lx sfar %016lx\n", spitfire_get_dsfsr(), spitfire_get_sfar()); die_if_kernel("Data access exception", regs); } +void do_dae(struct pt_regs *regs) +{ + printk("DAE: at %016lx\n", regs->tpc); + while(1) + barrier(); +} + void instruction_access_exception (struct pt_regs *regs) { - printk ("Unhandled instruction access exception sfsr %016lx\n", spitfire_get_isfsr()); + lock_kernel (); + printk ("Unhandled instruction access exception "); + printk("sfsr %016lx\n", spitfire_get_isfsr()); die_if_kernel("Instruction access exception", regs); } +void do_iae(struct pt_regs *regs) +{ + printk("IAE at %016lx\n", regs->tpc); + while(1) + barrier(); +} + +void do_fpdis(struct pt_regs *regs) +{ + printk("FPDIS: at %016lx\n", regs->tpc); + while(1) + barrier(); +} + +void do_fpieee(struct pt_regs *regs) +{ + printk("FPIEEE: at %016lx\n", regs->tpc); + while(1) + barrier(); +} + +void do_fpother(struct pt_regs *regs) +{ + printk("FPOTHER: at %016lx\n", regs->tpc); + while(1) + barrier(); +} + +void do_tof(struct pt_regs *regs) +{ + printk("TOF: at %016lx\n", regs->tpc); + while(1) + barrier(); +} + +void do_div0(struct pt_regs *regs) +{ + printk("DIV0: at %016lx\n", regs->tpc); + while(1) + barrier(); +} + void instruction_dump (unsigned int *pc) { int i; @@ -116,11 +311,27 @@ void die_if_kernel(char *str, struct pt_regs *regs) " \\__U_/\n"); printk("%s(%d): %s\n", current->comm, current->pid, str); + __asm__ __volatile__("flushw"); show_regs(regs); + { + struct reg_window *rw = (struct reg_window *) + (regs->u_regs[UREG_FP] + STACK_BIAS); + + if(rw) { + printk("Caller[%016lx]\n", rw->ins[7]); + rw = (struct reg_window *) + (rw->ins[6] + STACK_BIAS); + if(rw) { + printk("Caller[%016lx]\n", rw->ins[7]); + rw = (struct reg_window *) + (rw->ins[6] + STACK_BIAS); + if(rw) + printk("Caller[%016lx]\n", rw->ins[7]); + } + } + } printk("Instruction DUMP:"); instruction_dump ((unsigned int *) regs->tpc); - while(1) - barrier(); if(regs->tstate & TSTATE_PRIV) do_exit(SIGKILL); do_exit(SIGSEGV); @@ -160,6 +371,20 @@ void do_mna(struct pt_regs *regs) barrier(); } +void do_privop(struct pt_regs *regs) +{ + printk("PRIVOP: at %016lx\n", regs->tpc); + while(1) + barrier(); +} + +void do_privact(struct pt_regs *regs) +{ + printk("PRIVACT: at %016lx\n", regs->tpc); + while(1) + barrier(); +} + void do_priv_instruction(struct pt_regs *regs, unsigned long pc, unsigned long npc, unsigned long tstate) { diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c index dc28ac339..e23e736a9 100644 --- a/arch/sparc64/mm/fault.c +++ b/arch/sparc64/mm/fault.c @@ -1,4 +1,4 @@ -/* $Id: fault.c,v 1.8 1997/05/18 04:16:52 davem Exp $ +/* $Id: fault.c,v 1.9 1997/05/19 05:58:54 davem Exp $ * arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -150,13 +150,13 @@ asmlinkage void do_sparc64_fault(struct pt_regs *regs, int text_fault, int write static unsigned long last_addr = 0; static int rcnt = 0; - printk("do_sparc64_fault(PC[%016lx],t[%d],w[%d],addr[%016lx]tag[%016lx]" - "sfar[%016lx])\n", regs->tpc, text_fault, write, address, tag, sfsr); + printk("FAULT(PC[%016lx],t[%d],w[%d],addr[%016lx])\n", + regs->tpc, text_fault, write, address); if(address == last_addr && rcnt++ > 5) { printk("Wheee lotsa bogus faults, something wrong, spinning\n"); while(1) barrier(); - } + } else rcnt = 0; last_addr = address; #endif lock_kernel (); diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index cf378a266..960b3cbbd 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.28 1997/05/18 04:16:53 davem Exp $ +/* $Id: init.c,v 1.29 1997/05/27 06:28:13 davem Exp $ * arch/sparc64/mm/init.c * * Copyright (C) 1996,1997 David S. Miller (davem@caip.rutgers.edu) @@ -269,10 +269,14 @@ void mmu_get_scsi_sgl(struct mmu_sglist *sg, int sz, struct linux_sbus *sbus) } } +static char sfmmuinfo[512]; + char *mmu_info(void) { - /* XXX */ - return "MMU Type: Spitfire\n\tFIXME: Write this\n"; + /* We'll do the rest later to make it nice... -DaveM */ + sprintf(sfmmuinfo, "MMU Type\t: Spitfire\n"); + + return sfmmuinfo; } static unsigned long mempool; |